
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_Hans">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>QuerySet API 参考 &#8212; Django 3.2.11.dev 文档</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/language_data.js"></script>
    <link rel="index" title="索引" href="../../genindex.html" />
    <link rel="search" title="搜索" href="../../search.html" />
    <link rel="next" title="查找 API 参考" href="lookups.html" />
    <link rel="prev" title="模型实例参考" href="instances.html" />



 
<script src="../../templatebuiltins.js"></script>
<script>
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django 3.2.11.dev 文档</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="instances.html" title="模型实例参考">previous</a>
     |
    <a href="../index.html" title="API 参考" accesskey="U">up</a>
   |
    <a href="lookups.html" title="查找 API 参考">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="ref-models-querysets">
            
  <div class="section" id="s-queryset-api-reference">
<span id="queryset-api-reference"></span><h1><code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> API 参考<a class="headerlink" href="#queryset-api-reference" title="永久链接至标题">¶</a></h1>
<p>该文档描述了 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> API 的细节。它是建立在 <a class="reference internal" href="../../topics/db/models.html"><span class="doc">模型</span></a> 和 <a class="reference internal" href="../../topics/db/queries.html"><span class="doc">数据库查询</span></a> 指南的材料基础上的，因此，在阅读这篇文档之前，你可能需要阅读和理解这些文档。</p>
<p>在整篇参考中，我们将使用 <a class="reference internal" href="../../topics/db/queries.html"><span class="doc">数据库查询指南</span></a> 中的 <a class="reference internal" href="../../topics/db/queries.html#queryset-model-example"><span class="std std-ref">Weblog 示例模型</span></a> 。</p>
<div class="section" id="s-when-querysets-are-evaluated">
<span id="s-id1"></span><span id="when-querysets-are-evaluated"></span><span id="id1"></span><h2>什么时候 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 被执行<a class="headerlink" href="#when-querysets-are-evaluated" title="永久链接至标题">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 本身可以被构造，过滤，切片，或者复制赋值等，是无需访问数据库的。只有在你需要从数据库取出数据或者，向数据库存入数据时才需要访问数据库。</p>
<p>你可以用以下方式执行一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>：</p>
<ul>
<li><p class="first"><strong>迭代。</strong> 一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 是可迭代的，当你第一次迭代它时，它就会执行其数据库查询。例如，这将打印数据库中所有条目的标题：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">headline</span><span class="p">)</span>
</pre></div>
</div>
<p>注意：如果你想做的只是确定至少一个结果是否存在，不要使用这个。使用 <a class="reference internal" href="#django.db.models.query.QuerySet.exists" title="django.db.models.query.QuerySet.exists"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exists()</span></code></a> 会更有效。</p>
</li>
<li><p class="first"><strong>切片。</strong> 正如在 <a class="reference internal" href="../../topics/db/queries.html#limiting-querysets"><span class="std std-ref">限制 QuerySet 条目数</span></a> 中所解释的那样，<code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 可以使用 Python 的数组切片语法进行切片。切片一个未执行的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 通常会返回另一个未执行的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，但如果使用切片语法的 <code class="docutils literal notranslate"><span class="pre">step</span></code> 参数，Django 会执行数据库查询，并返回一个列表。切片一个已经执行过的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 也会返回一个列表。</p>
<p>还要注意的是，即使对一个未执行的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 进行切片，返回另一个未执行的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，也不允许进一步修改它（例如，添加更多的过滤器，或修改排序），因为这不能很好地翻译成 SQL，也没有明确的含义。</p>
</li>
<li><p class="first"><strong>Pickle 序列化／缓存。</strong> 关于 <a class="reference internal" href="#pickling-querysets">pickling QuerySets</a> 时涉及的细节，请参见下一节。就本节而言，重要的是，结果是从数据库中读取的。</p>
</li>
<li><p class="first"><strong>repr()。</strong> 当你调用 <code class="docutils literal notranslate"><span class="pre">repr()</span></code> 时，所在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 会被执行。这是为了方便 Python 交互式解释器，所以当你交互式使用 API 时，可以立即看到你的结果。</p>
</li>
<li><p class="first"><strong>len()。</strong> 当你调用 <code class="docutils literal notranslate"><span class="pre">len()</span></code> 时，会执行 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>。正如你所期望的，这将返回结果列表的长度。</p>
<p>注意：如果你只需要确定集合中的记录数（而不需要实际的对象），那么使用 SQL 的 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">COUNT(*)</span></code> 在数据库层面上处理计数会更有效率。Django 提供了一个 <a class="reference internal" href="#django.db.models.query.QuerySet.count" title="django.db.models.query.QuerySet.count"><code class="xref py py-meth docutils literal notranslate"><span class="pre">count()</span></code></a> 方法正是为了这个原因。</p>
</li>
<li><p class="first"><strong>list()。</strong> 通过调用 <code class="docutils literal notranslate"><span class="pre">list()</span></code> 强制执行 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entry_list</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">())</span>
</pre></div>
</div>
</li>
<li><p class="first"><strong>bool()。</strong> 在布尔语境中测试 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，如使用 <code class="docutils literal notranslate"><span class="pre">bool()</span></code>、<code class="docutils literal notranslate"><span class="pre">or</span></code>、<code class="docutils literal notranslate"><span class="pre">and</span></code> 或 <code class="docutils literal notranslate"><span class="pre">if</span></code> 语句，将导致查询被执行。如果至少有一个结果，则 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，否则为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s2">&quot;Test&quot;</span><span class="p">):</span>
   <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;There is at least one Entry with the headline Test&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>注意：如果你只想确定至少一个结果是否存在（而不需要实际的对象），使用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">exences()</span></code> 更高效。</p>
</li>
</ul>
<div class="section" id="s-pickling-querysets">
<span id="s-id2"></span><span id="pickling-querysets"></span><span id="id2"></span><h3>Pickle 序列化 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code><a class="headerlink" href="#pickling-querysets" title="永久链接至标题">¶</a></h3>
<p>如果你 <a class="reference external" href="https://docs.python.org/3/library/pickle.html#module-pickle" title="(在 Python v3.10)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">pickle</span></code></a> 序列化一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，这将迫使所有结果在 pickle 序列化之前加载到内存中。Pickle 序列化通常被用作缓存的前奏，当缓存的查询集被重新加载时，你希望结果已经存在并可以使用（从数据库读取可能需要一些时间，这就违背了缓存的目的）。这意味着，当你取消缓存一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 时，它包含的是它被缓存时的结果，而不是当前在数据库中的结果。</p>
<p>如果你只想提取必要的信息，以便以后从数据库中重新创建 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，则提取 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的 <code class="docutils literal notranslate"><span class="pre">query</span></code> 属性。然后，你可以使用这样的代码重新创建原始的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> （不加载任何结果）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pickle</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">query</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>     <span class="c1"># Assuming &#39;s&#39; is the pickled string.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span> <span class="o">=</span> <span class="n">MyModel</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span><span class="o">.</span><span class="n">query</span> <span class="o">=</span> <span class="n">query</span>            <span class="c1"># Restore the original &#39;query&#39;.</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">query</span></code> 属性是一个不透明的对象。它代表了查询结构的内部结构，不是公共 API 的一部分。但是，如这里所述，可以安全地（并完全支持）pickle 序列化和反序列化该属性的内容。</p>
<div class="admonition-restrictions-on-queryset-values-list admonition">
<p class="first admonition-title">Restrictions on <code class="docutils literal notranslate"><span class="pre">QuerySet.values_list()</span></code></p>
<p>If you recreate <a class="reference internal" href="#django.db.models.query.QuerySet.values_list" title="django.db.models.query.QuerySet.values_list"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.values_list()</span></code></a> using the pickled <code class="docutils literal notranslate"><span class="pre">query</span></code>
attribute, it will be converted to <a class="reference internal" href="#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.values()</span></code></a>:</p>
<div class="last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pickle</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span>
<span class="go">&lt;QuerySet [(1, &#39;Beatles Blog&#39;)]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">reloaded_qs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">reloaded_qs</span><span class="o">.</span><span class="n">query</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">pickle</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">qs</span><span class="o">.</span><span class="n">query</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">reloaded_qs</span>
<span class="go">&lt;QuerySet [{&#39;id&#39;: 1, &#39;name&#39;: &#39;Beatles Blog&#39;}]&gt;</span>
</pre></div>
</div>
</div>
<div class="admonition-you-can-t-share-pickles-between-versions admonition">
<p class="first admonition-title">你不能在不同版本之间共享 pickle</p>
<p><code class="docutils literal notranslate"><span class="pre">QuerySets</span></code> 的 pickle 只对生成它们的 Django 版本有效。如果你用 Django N 版本生成了一个 pickle，就不能保证这个 pickle 在 Django N+1 版本中可以被读取。Pickle 不应该作为长期存档策略的一部分。</p>
<p class="last">由于 pickle 兼容性错误可能很难诊断，比如静默损坏对象，所以当你试图在与序列化 pickle 时不同版本的 Django 中反序列化查询集时，会发出 <code class="docutils literal notranslate"><span class="pre">RuntimeWarning</span></code>。</p>
</div>
</div>
</div>
<div class="section" id="s-queryset-api">
<span id="s-id3"></span><span id="queryset-api"></span><span id="id3"></span><h2><code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> API<a class="headerlink" href="#queryset-api" title="永久链接至标题">¶</a></h2>
<p>这里是 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的正式声明：</p>
<dl class="class">
<dt id="django.db.models.query.QuerySet">
<em class="property">class </em><code class="descname">QuerySet</code>(<em>model=None</em>, <em>query=None</em>, <em>using=None</em>, <em>hints=None</em>)<a class="headerlink" href="#django.db.models.query.QuerySet" title="永久链接至目标">¶</a></dt>
<dd><p>通常当你与 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 交互时，你会通过 <a class="reference internal" href="../../topics/db/queries.html#chaining-filters"><span class="std std-ref">链式过滤器</span></a> 来使用它。为了实现这一目的，大多数 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 方法都会返回新的查询集。这些方法将在本节后面详细介绍。</p>
<p><code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 类具有两个可用于自省的公开属性：</p>
<dl class="attribute">
<dt id="django.db.models.query.QuerySet.ordered">
<code class="descname">ordered</code><a class="headerlink" href="#django.db.models.query.QuerySet.ordered" title="永久链接至目标">¶</a></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">True</span></code> 如果 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 是有序的——即有一个 <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> 子句或模型上的默认排序。否则为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
</dd></dl>

<dl class="attribute">
<dt id="django.db.models.query.QuerySet.db">
<code class="descname">db</code><a class="headerlink" href="#django.db.models.query.QuerySet.db" title="永久链接至目标">¶</a></dt>
<dd><p>如果现在执行这个查询，将使用的数据库。</p>
</dd></dl>

<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last"><a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">query</span></code> 参数的存在是为了让专门的查询子类能够重建内部查询状态。该参数的值是该查询状态的不透明表示，不是公共 API 的一部分。</p>
</div>
</dd></dl>

<div class="section" id="s-methods-that-return-new-querysets">
<span id="methods-that-return-new-querysets"></span><h3>返回新 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的方法<a class="headerlink" href="#methods-that-return-new-querysets" title="永久链接至标题">¶</a></h3>
<p>Django 提供了一系列的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 细化方法，这些方法可以修改 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 返回的结果类型或其 SQL 查询的执行方式。</p>
<div class="section" id="s-filter">
<span id="filter"></span><h4><code class="docutils literal notranslate"><span class="pre">filter()</span></code><a class="headerlink" href="#filter" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.filter">
<code class="descname">filter</code>(<em>*args</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.filter" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个新的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，其中包含与给定查找参数相匹配的对象。</p>
<p>查询参数（<code class="docutils literal notranslate"><span class="pre">**kwargs</span></code>）的格式应在下文 <a class="reference internal" href="#id4">Field lookups</a> 中描述。多个参数通过底层 SQL 语句中的 <code class="docutils literal notranslate"><span class="pre">AND</span></code> 连接。</p>
<p>If you need to execute more complex queries (for example, queries with <code class="docutils literal notranslate"><span class="pre">OR</span></code> statements),
you can use <a class="reference internal" href="#django.db.models.Q" title="django.db.models.Q"><code class="xref py py-class docutils literal notranslate"><span class="pre">Q</span> <span class="pre">objects</span></code></a> (<code class="docutils literal notranslate"><span class="pre">*args</span></code>).</p>
</div>
<div class="section" id="s-exclude">
<span id="exclude"></span><h4><code class="docutils literal notranslate"><span class="pre">exclude()</span></code><a class="headerlink" href="#exclude" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.exclude">
<code class="descname">exclude</code>(<em>*args</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.exclude" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个新的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，其中包含与给定查找参数不匹配的对象。</p>
<p>查询参数（<code class="docutils literal notranslate"><span class="pre">**kwargs</span></code>）的格式应在下文 <a class="reference internal" href="#id4">Field lookups</a> 中描述。多个参数通过底层 SQL 语句中的 <code class="docutils literal notranslate"><span class="pre">AND</span></code> 连接，整个过程用 <code class="docutils literal notranslate"><span class="pre">NOT()</span></code> 括起来。</p>
<p>这个例子排除了所有 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 晚于 2005-1-3 且 <code class="docutils literal notranslate"><span class="pre">headline</span></code> 为“Hello”的条目：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">pub_date__gt</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">headline</span><span class="o">=</span><span class="s1">&#39;Hello&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>用 SQL 术语来说，它的值是：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span>
<span class="k">WHERE</span> <span class="k">NOT</span> <span class="p">(</span><span class="n">pub_date</span> <span class="o">&gt;</span> <span class="s1">&#39;2005-1-3&#39;</span> <span class="k">AND</span> <span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;Hello&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>这个例子不包括所有 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 晚于 2005-1-3 或 <code class="docutils literal notranslate"><span class="pre">headline</span></code> 为“Hello”的条目：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">pub_date__gt</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;Hello&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>用 SQL 术语来说，它的值是：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span>
<span class="k">WHERE</span> <span class="k">NOT</span> <span class="n">pub_date</span> <span class="o">&gt;</span> <span class="s1">&#39;2005-1-3&#39;</span>
<span class="k">AND</span> <span class="k">NOT</span> <span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;Hello&#39;</span>
</pre></div>
</div>
<p>请注意，第二个例子的限制性更强。</p>
<p>If you need to execute more complex queries (for example, queries with <code class="docutils literal notranslate"><span class="pre">OR</span></code> statements),
you can use <a class="reference internal" href="#django.db.models.Q" title="django.db.models.Q"><code class="xref py py-class docutils literal notranslate"><span class="pre">Q</span> <span class="pre">objects</span></code></a> (<code class="docutils literal notranslate"><span class="pre">*args</span></code>).</p>
</div>
<div class="section" id="s-annotate">
<span id="annotate"></span><h4><code class="docutils literal notranslate"><span class="pre">annotate()</span></code><a class="headerlink" href="#annotate" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.annotate">
<code class="descname">annotate</code>(<em>*args</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.annotate" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>用所提供的 <a class="reference internal" href="expressions.html"><span class="doc">查询表达式</span></a> 列表对 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的每个对象进行注解。表达式可以是一个简单的值，也可以是对模型（或任何相关模型）字段的引用，或者是对与 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的对象相关的对象进行计算的聚合表达式（平均数、总和等）。</p>
<p><code class="docutils literal notranslate"><span class="pre">annotate()</span></code> 的每个参数都是一个注解，将被添加到返回的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的每个对象。</p>
<p>Django 提供的聚合函数在下面的 <a class="reference internal" href="#id5">聚合函数</a> 中介绍。</p>
<p>使用关键字参数指定的注解将使用关键字作为注解的别名。匿名参数将根据聚合函数的名称和被聚合的模型字段为其生成一个别名。只有引用单个字段的聚合表达式才能成为匿名参数。其他一切都必须是关键字参数。</p>
<p>例如，如果你在操纵一个博客列表，你可能想确定每个博客中已经有多少条记录：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go"># The name of the first blog</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
<span class="go">&#39;Blogasaurus&#39;</span>
<span class="go"># The number of entries on the first blog</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">entry__count</span>
<span class="go">42</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">Blog</span></code> 模型本身并没有定义 <code class="docutils literal notranslate"><span class="pre">entry__count</span></code> 属性，但是通过使用关键字参数来指定聚合函数，可以控制注解的名称：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">q</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">number_of_entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go"># The number of entries on the first blog, using the name provided</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">number_of_entries</span>
<span class="go">42</span>
</pre></div>
</div>
<p>关于聚合的深入讨论，见 <a class="reference internal" href="../../topics/db/aggregation.html"><span class="doc">关于聚合的专题指南</span></a>。</p>
</div>
<div class="section" id="s-alias">
<span id="alias"></span><h4><code class="docutils literal notranslate"><span class="pre">alias()</span></code><a class="headerlink" href="#alias" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.alias">
<code class="descname">alias</code>(<em>*args</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.alias" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<div class="versionadded">
<span class="title">New in Django 3.2.</span> </div>
<p>Same as <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a>, but instead of annotating objects in the
<code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>, saves the expression for later reuse with other <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>
methods. This is useful when the result of the expression itself is not needed
but it is used for filtering, ordering, or as a part of a complex expression.
Not selecting the unused value removes redundant work from the database which
should result in better performance.</p>
<p>For example, if you want to find blogs with more than 5 entries, but are not
interested in the exact number of entries, you could do this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">blogs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">alias</span><span class="p">(</span><span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">entries__gt</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">alias()</span></code> can be used in conjunction with <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a>, <a class="reference internal" href="#django.db.models.query.QuerySet.exclude" title="django.db.models.query.QuerySet.exclude"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exclude()</span></code></a>,
<a class="reference internal" href="#django.db.models.query.QuerySet.filter" title="django.db.models.query.QuerySet.filter"><code class="xref py py-meth docutils literal notranslate"><span class="pre">filter()</span></code></a>, <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a>, and <a class="reference internal" href="#django.db.models.query.QuerySet.update" title="django.db.models.query.QuerySet.update"><code class="xref py py-meth docutils literal notranslate"><span class="pre">update()</span></code></a>. To use aliased expression
with other methods (e.g. <a class="reference internal" href="#django.db.models.query.QuerySet.aggregate" title="django.db.models.query.QuerySet.aggregate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">aggregate()</span></code></a>), you must promote it to an
annotation:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">alias</span><span class="p">(</span><span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span>
    <span class="n">entries</span><span class="o">=</span><span class="n">F</span><span class="p">(</span><span class="s1">&#39;entries&#39;</span><span class="p">),</span>
<span class="p">)</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">Sum</span><span class="p">(</span><span class="s1">&#39;entries&#39;</span><span class="p">))</span>
</pre></div>
</div>
<p><a class="reference internal" href="#django.db.models.query.QuerySet.filter" title="django.db.models.query.QuerySet.filter"><code class="xref py py-meth docutils literal notranslate"><span class="pre">filter()</span></code></a> and <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> can take expressions directly, but
expression construction and usage often does not happen in the same place (for
example, <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> method creates expressions, for later use in views).
<code class="docutils literal notranslate"><span class="pre">alias()</span></code> allows building complex expressions incrementally, possibly
spanning multiple methods and modules, refer to the expression parts by their
aliases and only use <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a> for the final result.</p>
</div>
<div class="section" id="s-order-by">
<span id="order-by"></span><h4><code class="docutils literal notranslate"><span class="pre">order_by()</span></code><a class="headerlink" href="#order-by" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.order_by">
<code class="descname">order_by</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.order_by" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>默认情况下，<code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 返回的结果是按照模型 <code class="docutils literal notranslate"><span class="pre">Meta</span></code> 中的 <code class="docutils literal notranslate"><span class="pre">ordering</span></code> 选项给出的排序元组排序的。你可以通过使用 <code class="docutils literal notranslate"><span class="pre">order_by</span></code> 方法在每个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的基础上覆盖这一点。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="mi">2005</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;headline&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>上述结果将按 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 降序排列，然后按 <code class="docutils literal notranslate"><span class="pre">headline</span></code> 升序排列。<code class="docutils literal notranslate"><span class="pre">&quot;-pub_date&quot;</span></code> 前面的负号表示 <em>降序</em>。升序是隐含的。要随机排序，使用 <code class="docutils literal notranslate"><span class="pre">&quot;?&quot;</span></code>，如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;?&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>注意：<code class="docutils literal notranslate"><span class="pre">order_by('?')</span></code> 查询可能会很贵，而且速度很慢，这取决于你使用的数据库后端。</p>
<p>要按不同模型中的字段排序，使用与跨模型关系查询时相同的语法。也就是说，字段的名称，后面是双下划线（<code class="docutils literal notranslate"><span class="pre">__</span></code>），再后面是新模型中的字段名称，以此类推，想加入多少模型就加入多少。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog__name&#39;</span><span class="p">,</span> <span class="s1">&#39;headline&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>如果你试图通过与另一个模型有关系的字段进行排序，Django 将使用相关模型上的默认排序，如果没有指定 <a class="reference internal" href="options.html#django.db.models.Options.ordering" title="django.db.models.Options.ordering"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Meta.ordering</span></code></a>，则通过相关模型的主键进行排序。例如，由于 <code class="docutils literal notranslate"><span class="pre">Blog</span></code> 模型没有指定默认排序：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>...等同于：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog__id&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>如果 <code class="docutils literal notranslate"><span class="pre">Blog</span></code> 有 <code class="docutils literal notranslate"><span class="pre">ordering</span> <span class="pre">=</span> <span class="pre">['name']</span></code>，那么第一个查询集将与以下内容相同：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog__name&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>你也可以通过在表达式上调用 <a class="reference internal" href="expressions.html#django.db.models.Expression.asc" title="django.db.models.Expression.asc"><code class="xref py py-meth docutils literal notranslate"><span class="pre">asc()</span></code></a> 或 <code class="xref py py-meth docutils literal notranslate"><span class="pre">esc()</span></code>，按 <a class="reference internal" href="expressions.html"><span class="doc">查询表达式</span></a> 排序：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">Coalesce</span><span class="p">(</span><span class="s1">&#39;summary&#39;</span><span class="p">,</span> <span class="s1">&#39;headline&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">desc</span><span class="p">())</span>
</pre></div>
</div>
<p><a class="reference internal" href="expressions.html#django.db.models.Expression.asc" title="django.db.models.Expression.asc"><code class="xref py py-meth docutils literal notranslate"><span class="pre">asc()</span></code></a> 和 <code class="xref py py-meth docutils literal notranslate"><span class="pre">esc()</span></code> 有参数（<code class="docutils literal notranslate"><span class="pre">nulls_first</span></code> 和 <code class="docutils literal notranslate"><span class="pre">nulls_last</span></code>）来控制如何对空值进行排序。</p>
<p>如果你还使用 <a class="reference internal" href="#django.db.models.query.QuerySet.distinct" title="django.db.models.query.QuerySet.distinct"><code class="xref py py-meth docutils literal notranslate"><span class="pre">distinct()</span></code></a>，在按相关模型中的字段排序时要谨慎。请参见 <a class="reference internal" href="#django.db.models.query.QuerySet.distinct" title="django.db.models.query.QuerySet.distinct"><code class="xref py py-meth docutils literal notranslate"><span class="pre">distinct()</span></code></a> 中的说明，解释相关模型排序如何改变预期结果。</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>允许指定一个多值字段来对结果进行排序（例如，一个 <a class="reference internal" href="fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyField</span></code></a> 字段，或者一个 <a class="reference internal" href="fields.html#django.db.models.ForeignKey" title="django.db.models.ForeignKey"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForeignKey</span></code></a> 字段的反向关系）。</p>
<p>考虑到这种情况：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Event</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
   <span class="n">parent</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span>
       <span class="s1">&#39;self&#39;</span><span class="p">,</span>
       <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">,</span>
       <span class="n">related_name</span><span class="o">=</span><span class="s1">&#39;children&#39;</span><span class="p">,</span>
   <span class="p">)</span>
   <span class="n">date</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateField</span><span class="p">()</span>

<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;children__date&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>在这里，每个 <code class="docutils literal notranslate"><span class="pre">Event</span></code> 可能有多个排序数据；每个 <code class="docutils literal notranslate"><span class="pre">Event</span></code> 有多个 <code class="docutils literal notranslate"><span class="pre">children</span></code> 将被多次返回到 <code class="docutils literal notranslate"><span class="pre">order_by()</span></code> 创建的新 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中。换句话说，在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 上使用 <code class="docutils literal notranslate"><span class="pre">order_by()</span></code> 可能会返回比你一开始工作更多的项目——这可能既不是预期的，也不是有用的。</p>
<p class="last">因此，在使用多值字段对结果进行排序时要注意。<strong>如果</strong> 你能确定你要订购的每个项目只有一个订购数据，这种方法应该不会出现问题。如果不是，请确保结果是你所期望的。</p>
</div>
<p>没有办法指定排序是否应该区分大小写。关于大小写敏感，Django 会按照数据库后台的正常排序方式来排序。</p>
<p>你可以用 <code class="xref py py-class docutils literal notranslate"><span class="pre">Lower</span></code> 将一个字段转换为小写，从而实现大小写一致的排序：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">Lower</span><span class="p">(</span><span class="s1">&#39;headline&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">desc</span><span class="p">())</span>
</pre></div>
</div>
<p>如果你不想在查询中应用任何排序，甚至是默认的排序，可以不使用参数调用 <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a>。</p>
<p>你可以通过检查 <a class="reference internal" href="#django.db.models.query.QuerySet.ordered" title="django.db.models.query.QuerySet.ordered"><code class="xref py py-attr docutils literal notranslate"><span class="pre">QuerySet.ordered</span></code></a> 属性来判断一个查询是否被排序，如果 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 以任何方式被排序，则该属性为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p>每次 <code class="docutils literal notranslate"><span class="pre">order_by()</span></code> 调用都将清除以前的任何排序。例如，此查询将按 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 而不是 <code class="docutils literal notranslate"><span class="pre">headline</span></code> 排序：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;headline&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p>排序不是一个免费的操作。你添加到排序中的每个字段都会给你的数据库带来成本。你添加的每个外键都会隐式地包含其所有的默认排序。</p>
<p class="last">如果查询没有指定顺序，那么结果将以未指定的顺序从数据库中返回。只有当按一组字段排序时，才能保证特定的排序，这些字段唯一地标识结果中的每个对象。例如，如果 <code class="docutils literal notranslate"><span class="pre">name</span></code> 字段不是唯一的，那么按它排序就不能保证具有相同名称的对象总是以相同的顺序出现。</p>
</div>
</div>
<div class="section" id="s-reverse">
<span id="reverse"></span><h4>reverse()<a class="headerlink" href="#reverse" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.reverse">
<code class="descname">reverse</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.reverse" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>使用 <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> 方法来反向返回查询集元素的顺序。第二次调用 <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> 会将顺序恢复到正常方向。</p>
<p>要检索一个查询集中的“最后”五个项目，你可以这样做：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_queryset</span><span class="o">.</span><span class="n">reverse</span><span class="p">()[:</span><span class="mi">5</span><span class="p">]</span>
</pre></div>
</div>
<p>请注意，这与 Python 中从一个序列的末尾切分不太一样。上面的例子会先返回最后一项，然后返回倒数第二项，以此类推。如果我们有一个 Python 序列，看 <code class="docutils literal notranslate"><span class="pre">seq[-5:]</span></code>，我们会先看到倒数第五项。Django 不支持这种访问模式（从末尾切分），因为在 SQL 中不可能有效地做到这一点。</p>
<p>另外，请注意，<code class="docutils literal notranslate"><span class="pre">reverse()</span></code> 一般只应在有定义顺序的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 上调用（例如，当对定义了默认顺序的模型进行查询时，或者当使用 <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> 时）。如果没有为一个给定的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 定义这样的排序，对它调用 <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> 没有实际效果（在调用 <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> 之前，排序是未定义的，之后也将保持未定义）。</p>
</div>
<div class="section" id="s-distinct">
<span id="distinct"></span><h4><code class="docutils literal notranslate"><span class="pre">distinct()</span></code><a class="headerlink" href="#distinct" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.distinct">
<code class="descname">distinct</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.distinct" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个新的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，在其 SQL 查询中使用 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">DISTINCT</span></code>。这将消除查询结果中的重复记录。</p>
<p>默认情况下，<code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 不会消除重复的记录。在实践中，这很少是一个问题，因为简单的查询，如 <code class="docutils literal notranslate"><span class="pre">Blog.objects.all()</span></code> 不会引入重复结果行的可能性。但是，如果你的查询跨越了多个表，当 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 被执行时，就有可能得到重复的结果。这时就应该使用 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code>。</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p><a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> 调用中使用的任何字段都包含在 SQL <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 列中。当与 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code> 结合使用时，这有时会导致意外的结果。如果按相关模型中的字段排序，这些字段将被添加到选定的列中，它们可能会使原本重复的行看起来是不同的。由于额外的列不会出现在返回的结果中（它们只是为了支持排序），所以有时看起来像是返回了非去重的结果。</p>
<p>同样，如果使用 <a class="reference internal" href="#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a> 查询来限制所选的列，任何 <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> 中使用的列（或默认的模型排序）仍然会被涉及，并可能影响结果的唯一性。</p>
<p class="last">这里的寓意是，如果你使用 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code>，要小心按相关模型排序。同样，当同时使用 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code> 和 <a class="reference internal" href="#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a> 时，在按 <a class="reference internal" href="#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a> 调用中没有的字段排序时要小心。</p>
</div>
<p>仅在 PostgreSQL 上，你可以传递位置参数（<code class="docutils literal notranslate"><span class="pre">*fields</span></code>），以指定 <code class="docutils literal notranslate"><span class="pre">DISTINCT</span></code> 应适用的字段名称。这相当于一个 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">DISTINCT</span> <span class="pre">ON</span></code> 的 SQL 查询。这其中的区别是，对于普通的 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code> 调用，数据库在确定哪些行是不同的时候，会比较每行中的 <em>每个</em> 字段。对于带有指定字段名的 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code> 调用，数据库将只比较指定的字段名。</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>当你指定字段名时，你 <em>必须</em> 在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中提供一个 <code class="docutils literal notranslate"><span class="pre">order_by()</span></code>，而且 <code class="docutils literal notranslate"><span class="pre">order_by()</span></code> 中的字段必须以 <code class="docutils literal notranslate"><span class="pre">distinct()</span></code> 中的字段开始，顺序相同。</p>
<p class="last">例如，<code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">DISTINCT</span> <span class="pre">ON</span> <span class="pre">(a)</span></code> 给出了列 <code class="docutils literal notranslate"><span class="pre">a</span></code> 中每个值的第一行。如果你不指定顺序，你会得到一些任意的行。</p>
</div>
<p>例子（第一个例子之后的例子只适用于 PostgreSQL）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Author</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">distinct</span><span class="p">()</span>
<span class="go">[...]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">)</span>
<span class="go">[...]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span>
<span class="go">[...]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;author&#39;</span><span class="p">,</span> <span class="s1">&#39;pub_date&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;author&#39;</span><span class="p">,</span> <span class="s1">&#39;pub_date&#39;</span><span class="p">)</span>
<span class="go">[...]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog__name&#39;</span><span class="p">,</span> <span class="s1">&#39;mod_date&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;blog__name&#39;</span><span class="p">,</span> <span class="s1">&#39;mod_date&#39;</span><span class="p">)</span>
<span class="go">[...]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;author&#39;</span><span class="p">,</span> <span class="s1">&#39;pub_date&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;author&#39;</span><span class="p">)</span>
<span class="go">[...]</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>请记住 <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> 使用任何已经定义的默认相关模型排序。你可能必须明确地按关系 <code class="docutils literal notranslate"><span class="pre">_id</span></code> 或引用字段排序，以确保 <code class="docutils literal notranslate"><span class="pre">DISTINCT</span> <span class="pre">ON</span></code> 表达式与 <code class="docutils literal notranslate"><span class="pre">ORDER</span> <span class="pre">BY</span></code> 子句开头的表达式匹配。例如，如果 <code class="docutils literal notranslate"><span class="pre">Blog</span></code> 模型定义了一个通过 <code class="docutils literal notranslate"><span class="pre">name</span></code> 进行 <code class="xref py py-attr docutils literal notranslate"> <span class="pre">ordering</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p class="last">...这是不可行的，因为查询将按 <code class="docutils literal notranslate"><span class="pre">blog__name</span></code> 排序，从而与 <code class="docutils literal notranslate"><span class="pre">DISTINCT</span> <span class="pre">ON</span></code> 表达式不匹配。你必须明确地按关系 <code class="docutils literal notranslate"><span class="pre">_id</span></code> 字段（本例中为 <code class="docutils literal notranslate"><span class="pre">blog_id</span></code>）或被引用的字段（<code class="docutils literal notranslate"><span class="pre">blog__pk</span></code>）排序，以确保两个表达式匹配。</p>
</div>
</div>
<div class="section" id="s-values">
<span id="values"></span><h4><code class="docutils literal notranslate"><span class="pre">values()</span></code><a class="headerlink" href="#values" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.values">
<code class="descname">values</code>(<em>*fields</em>, <em>**expressions</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.values" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，当用作可迭代对象时，返回字典，而不是模型实例。</p>
<p>其中每一个字典都代表一个对象，键与模型对象的属性名相对应。</p>
<p>本例将 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 的字典与普通模型对象进行比较：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># This list contains a Blog object.</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__startswith</span><span class="o">=</span><span class="s1">&#39;Beatles&#39;</span><span class="p">)</span>
<span class="o">&lt;</span><span class="n">QuerySet</span> <span class="p">[</span><span class="o">&lt;</span><span class="n">Blog</span><span class="p">:</span> <span class="n">Beatles</span> <span class="n">Blog</span><span class="o">&gt;</span><span class="p">]</span><span class="o">&gt;</span>

<span class="c1"># This list contains a dictionary.</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__startswith</span><span class="o">=</span><span class="s1">&#39;Beatles&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="o">&lt;</span><span class="n">QuerySet</span> <span class="p">[{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="s1">&#39;Beatles Blog&#39;</span><span class="p">,</span> <span class="s1">&#39;tagline&#39;</span><span class="p">:</span> <span class="s1">&#39;All the latest Beatles news.&#39;</span><span class="p">}]</span><span class="o">&gt;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">values()</span></code> 方法接受可选的位置参数 <code class="docutils literal notranslate"><span class="pre">*fields</span></code>，它指定了 <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 应该被限制的字段名。如果你指定了字段，每个字典将只包含你指定字段的字段键／值。如果不指定字段，每个字典将包含数据库表中每个字段的键和值。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="go">&lt;QuerySet [{&#39;id&#39;: 1, &#39;name&#39;: &#39;Beatles Blog&#39;, &#39;tagline&#39;: &#39;All the latest Beatles news.&#39;}]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [{&#39;id&#39;: 1, &#39;name&#39;: &#39;Beatles Blog&#39;}]&gt;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">values()</span></code> 方法也接受可选的关键字参数 <code class="docutils literal notranslate"><span class="pre">**expressions</span></code>，这些参数被传递给 <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models.functions</span> <span class="kn">import</span> <span class="n">Lower</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="n">lower_name</span><span class="o">=</span><span class="n">Lower</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [{&#39;lower_name&#39;: &#39;beatles blog&#39;}]&gt;</span>
</pre></div>
</div>
<p>你可以在排序中使用内置和 <a class="reference internal" href="../../howto/custom-lookups.html"><span class="doc">自定义查找</span></a>。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">CharField</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models.functions</span> <span class="kn">import</span> <span class="n">Lower</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">CharField</span><span class="o">.</span><span class="n">register_lookup</span><span class="p">(</span><span class="n">Lower</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;name__lower&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [{&#39;name__lower&#39;: &#39;beatles blog&#39;}]&gt;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">values()</span></code> 子句中的集合在同一 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 子句中的其他参数之前应用。如果你需要用另一个值来分组，可以把它添加到前面的 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 子句中。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;entry__authors&#39;</span><span class="p">,</span> <span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [{&#39;entry__authors&#39;: 1, &#39;entries&#39;: 20}, {&#39;entry__authors&#39;: 1, &#39;entries&#39;: 13}]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;entry__authors&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [{&#39;entry__authors&#39;: 1, &#39;entries&#39;: 33}]&gt;</span>
</pre></div>
</div>
<p>有几个微妙的地方值得一提：</p>
<ul>
<li><p class="first">如果你有一个名为 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 的字段是一个 <a class="reference internal" href="fields.html#django.db.models.ForeignKey" title="django.db.models.ForeignKey"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForeignKey</span></code></a>，默认的 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 调用将返回一个名为 <code class="docutils literal notranslate"><span class="pre">foo_id</span></code> 的字典键，因为这是存储实际值的隐藏模型属性的名称（<code class="docutils literal notranslate"><span class="pre">foo</span></code> 属性指的是相关模型）。当你调用 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 并传递字段名时，你可以传递 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 或 <code class="docutils literal notranslate"><span class="pre">foo_id</span></code>，你将得到同样的东西（字典键将与你传递的字段名匹配）。</p>
<p>例子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="go">&lt;QuerySet [{&#39;blog_id&#39;: 1, &#39;headline&#39;: &#39;First Entry&#39;, ...}, ...]&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [{&#39;blog&#39;: 1}, ...]&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;blog_id&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [{&#39;blog_id&#39;: 1}, ...]&gt;</span>
</pre></div>
</div>
</li>
<li><p class="first">当使用 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 与 <a class="reference internal" href="#django.db.models.query.QuerySet.distinct" title="django.db.models.query.QuerySet.distinct"><code class="xref py py-meth docutils literal notranslate"><span class="pre">distinct()</span></code></a> 一起使用时，请注意排序会影响结果。详见 <a class="reference internal" href="#django.db.models.query.QuerySet.distinct" title="django.db.models.query.QuerySet.distinct"><code class="xref py py-meth docutils literal notranslate"><span class="pre">distinct()</span></code></a> 中的说明。</p>
</li>
<li><p class="first">如果在 <a class="reference internal" href="#django.db.models.query.QuerySet.extra" title="django.db.models.query.QuerySet.extra"><code class="xref py py-meth docutils literal notranslate"><span class="pre">extra()</span></code></a> 调用之后使用 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 子句，则 <a class="reference internal" href="#django.db.models.query.QuerySet.extra" title="django.db.models.query.QuerySet.extra"><code class="xref py py-meth docutils literal notranslate"><span class="pre">extra()</span></code></a> 中的 <code class="docutils literal notranslate"><span class="pre">select</span></code> 参数所定义的任何字段必须明确地包含在 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 调用中。任何在 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 调用之后进行的 <a class="reference internal" href="#django.db.models.query.QuerySet.extra" title="django.db.models.query.QuerySet.extra"><code class="xref py py-meth docutils literal notranslate"><span class="pre">extra()</span></code></a> 调用将忽略其额外选择的字段。</p>
</li>
<li><p class="first">在 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 之后调用 <a class="reference internal" href="#django.db.models.query.QuerySet.only" title="django.db.models.query.QuerySet.only"><code class="xref py py-meth docutils literal notranslate"><span class="pre">only()</span></code></a> 和 <a class="reference internal" href="#django.db.models.query.QuerySet.defer" title="django.db.models.query.QuerySet.defer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">defer()</span></code></a> 是没有意义的，这样做会引发 <code class="docutils literal notranslate"><span class="pre">TypeError</span></code>。</p>
</li>
<li><p class="first">结合变换和聚合需要使用两个 <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a> 调用，可以是显式的，也可以是 <a class="reference internal" href="#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a> 的关键字参数。如上所述，如果已经在相关字段类型上注册了变换，那么第一个 <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a> 可以省略，因此以下例子是等价的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">CharField</span><span class="p">,</span> <span class="n">Count</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models.functions</span> <span class="kn">import</span> <span class="n">Lower</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">CharField</span><span class="o">.</span><span class="n">register_lookup</span><span class="p">(</span><span class="n">Lower</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;entry__authors__name__lower&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [{&#39;entry__authors__name__lower&#39;: &#39;test author&#39;, &#39;entries&#39;: 33}]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">entry__authors__name__lower</span><span class="o">=</span><span class="n">Lower</span><span class="p">(</span><span class="s1">&#39;entry__authors__name&#39;</span><span class="p">)</span>
<span class="gp">... </span><span class="p">)</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [{&#39;entry__authors__name__lower&#39;: &#39;test author&#39;, &#39;entries&#39;: 33}]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">entry__authors__name__lower</span><span class="o">=</span><span class="n">Lower</span><span class="p">(</span><span class="s1">&#39;entry__authors__name&#39;</span><span class="p">)</span>
<span class="gp">... </span><span class="p">)</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;entry__authors__name__lower&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [{&#39;entry__authors__name__lower&#39;: &#39;test author&#39;, &#39;entries&#39;: 33}]&gt;</span>
</pre></div>
</div>
</li>
</ul>
<p>当你知道你只需要一小部分可用字段的值，而且你不需要模型实例对象的功能时，它就很有用。只选择你需要使用的字段会更高效。</p>
<p>最后要注意的是，你可以在调用 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 之后调用 <code class="docutils literal notranslate"><span class="pre">filter()</span></code>、<code class="docutils literal notranslate"><span class="pre">order_by()</span></code> 等，也就是说这两个调用是相同的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">()</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
</pre></div>
</div>
<p>制作 Django 的人喜欢把所有影响 SQL 的方法放在前面，后面（可选的）是任何影响输出的方法（比如 <code class="docutils literal notranslate"><span class="pre">values()</span></code>），但这并不重要。这是你真正炫耀自己个性的机会。</p>
<p>你也可以通过 <code class="docutils literal notranslate"><span class="pre">OneToOneField</span></code>、<code class="docutils literal notranslate"><span class="pre">ForeignKey</span></code> 和 <code class="docutils literal notranslate"><span class="pre">ManyToManyField</span></code> 属性来引用相关模型上具有反向关系的字段：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;entry__headline&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [{&#39;name&#39;: &#39;My blog&#39;, &#39;entry__headline&#39;: &#39;An entry&#39;},</span>
<span class="go">     {&#39;name&#39;: &#39;My blog&#39;, &#39;entry__headline&#39;: &#39;Another entry&#39;}, ...]&gt;</span>
</pre></div>
</div>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">因为 <a class="reference internal" href="fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyField</span></code></a> 属性和逆向关系可以有多条相关的记录，包括这些可以对你的结果集的大小产生倍增效应。如果你在你的 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 查询中包含了多个这样的字段，这一点会特别明显，在这种情况下，所有可能的组合都会被返回。</p>
</div>
<div class="admonition-boolean-values-for-jsonfield-on-sqlite admonition">
<p class="first admonition-title">Boolean values for <code class="docutils literal notranslate"><span class="pre">JSONField</span></code> on SQLite</p>
<p class="last">Due to the way the <code class="docutils literal notranslate"><span class="pre">JSON_EXTRACT</span></code> SQL function is implemented on SQLite,
<code class="docutils literal notranslate"><span class="pre">values()</span></code> will return <code class="docutils literal notranslate"><span class="pre">1</span></code> and <code class="docutils literal notranslate"><span class="pre">0</span></code> instead of <code class="docutils literal notranslate"><span class="pre">True</span></code> and <code class="docutils literal notranslate"><span class="pre">False</span></code>
for <a class="reference internal" href="fields.html#django.db.models.JSONField" title="django.db.models.JSONField"><code class="xref py py-class docutils literal notranslate"><span class="pre">JSONField</span></code></a> key transforms.</p>
</div>
</div>
<div class="section" id="s-values-list">
<span id="values-list"></span><h4><code class="docutils literal notranslate"><span class="pre">values_list()</span></code><a class="headerlink" href="#values-list" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.values_list">
<code class="descname">values_list</code>(<em>*fields</em>, <em>flat=False</em>, <em>named=False</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.values_list" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>这与 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 类似，只是在迭代时不返回字典，而是返回元组。每一个元组都包含了传入 <code class="docutils literal notranslate"><span class="pre">values_list()</span></code> 调用的各个字段或表达式的值——所以第一项是第一个字段，等等。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;headline&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [(1, &#39;First entry&#39;), ...]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models.functions</span> <span class="kn">import</span> <span class="n">Lower</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="n">Lower</span><span class="p">(</span><span class="s1">&#39;headline&#39;</span><span class="p">))</span>
<span class="go">&lt;QuerySet [(1, &#39;first entry&#39;), ...]&gt;</span>
</pre></div>
</div>
<p>如果你只传入一个字段，你也可以传入 <code class="docutils literal notranslate"><span class="pre">flat</span></code> 参数。如果 <code class="docutils literal notranslate"><span class="pre">True</span></code>，这将意味着返回的结果是单个值，而不是一个元组。一个例子应该可以更清楚地说明两者的区别：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet[(1,), (2,), (3,), ...]&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="n">flat</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [1, 2, 3, ...]&gt;</span>
</pre></div>
</div>
<p>当有多个字段时，传入 <code class="docutils literal notranslate"><span class="pre">flat</span></code> 是错误的。</p>
<p>你可以通过 <code class="docutils literal notranslate"><span class="pre">named=True</span></code> 来获取结果为 <a class="reference external" href="https://docs.python.org/3/library/collections.html#collections.namedtuple" title="(在 Python v3.10)"><code class="xref py py-func docutils literal notranslate"><span class="pre">namedtuple()</span></code></a>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;headline&#39;</span><span class="p">,</span> <span class="n">named</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">&lt;QuerySet [Row(id=1, headline=&#39;First entry&#39;), ...]&gt;</span>
</pre></div>
</div>
<p>使用命名元组可能会使使用结果更易读，但代价是将结果转化为命名元组时要付出很小的性能代价。</p>
<p>如果你不向 <code class="docutils literal notranslate"><span class="pre">values_list()</span></code> 传递任何值，它将按照声明的顺序返回模型中的所有字段。</p>
<p>一个常见的需求是获取某个模型实例的特定字段值。为了实现这一目标，使用 <code class="docutils literal notranslate"><span class="pre">values_list()</span></code>，然后调用 <code class="docutils literal notranslate"><span class="pre">get()</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;headline&#39;</span><span class="p">,</span> <span class="n">flat</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="go">&#39;First entry&#39;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">values()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">values_list()</span></code> 都是针对特定用例的优化：检索数据的子集，而不需要创建一个模型实例的开销。当处理多对多和其他多值关系（如反向外键的一对多关系）时，这个隐喻就失效了，因为“一行一对象”的假设不成立。</p>
<p>例如，请注意在跨 <a class="reference internal" href="fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyField</span></code></a> 查询时的行为：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Author</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;entry__headline&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [(&#39;Noam Chomsky&#39;, &#39;Impressions of Gaza&#39;),</span>
<span class="go"> (&#39;George Orwell&#39;, &#39;Why Socialists Do Not Believe in Fun&#39;),</span>
<span class="go"> (&#39;George Orwell&#39;, &#39;In Defence of English Cooking&#39;),</span>
<span class="go"> (&#39;Don Quixote&#39;, None)]&gt;</span>
</pre></div>
</div>
<p>有多个条目的作者出现多次，没有任何条目的作者的条目标题为 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
<p>同样，在查询反向外键时，对于没有任何作者的条目，会出现 <code class="docutils literal notranslate"><span class="pre">None</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;authors&#39;</span><span class="p">)</span>
<span class="go">&lt;QuerySet [(&#39;Noam Chomsky&#39;,), (&#39;George Orwell&#39;,), (None,)]&gt;</span>
</pre></div>
</div>
<div class="admonition-boolean-values-for-jsonfield-on-sqlite admonition">
<p class="first admonition-title">Boolean values for <code class="docutils literal notranslate"><span class="pre">JSONField</span></code> on SQLite</p>
<p class="last">Due to the way the <code class="docutils literal notranslate"><span class="pre">JSON_EXTRACT</span></code> SQL function is implemented on SQLite,
<code class="docutils literal notranslate"><span class="pre">values_list()</span></code> will return <code class="docutils literal notranslate"><span class="pre">1</span></code> and <code class="docutils literal notranslate"><span class="pre">0</span></code> instead of <code class="docutils literal notranslate"><span class="pre">True</span></code> and
<code class="docutils literal notranslate"><span class="pre">False</span></code> for <a class="reference internal" href="fields.html#django.db.models.JSONField" title="django.db.models.JSONField"><code class="xref py py-class docutils literal notranslate"><span class="pre">JSONField</span></code></a> key transforms.</p>
</div>
</div>
<div class="section" id="s-dates">
<span id="dates"></span><h4><code class="docutils literal notranslate"><span class="pre">dates()</span></code><a class="headerlink" href="#dates" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.dates">
<code class="descname">dates</code>(<em>field</em>, <em>kind</em>, <em>order='ASC'</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.dates" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，它的值是一个 <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.date" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.date</span></code></a> 对象的列表，代表 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 内容中所有可用的特定日期。</p>
<p><code class="docutils literal notranslate"><span class="pre">field</span></code> 应该是你的模型的 <code class="docutils literal notranslate"><span class="pre">DateField</span></code> 的名称。<code class="docutils literal notranslate"><span class="pre">kind</span></code> 应该是``&quot;year&quot;<code class="docutils literal notranslate"><span class="pre">、</span></code>&quot;month&quot;<code class="docutils literal notranslate"><span class="pre">、</span></code>&quot;week&quot;`` 或 <code class="docutils literal notranslate"><span class="pre">&quot;day&quot;</span></code>。结果列表中的每个 <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.date" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.date</span></code></a> 对象都被“截断”为给定的` <cite>type`</cite>。</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">&quot;year&quot;</span></code> 返回字段的所有不同年份值的列表。</li>
<li><code class="docutils literal notranslate"><span class="pre">&quot;month&quot;</span></code> 返回该字段所有不同年／月值的列表。</li>
<li><code class="docutils literal notranslate"><span class="pre">&quot;week&quot;</span></code> 返回该字段的所有不同年份／星期值的列表。所有日期都是星期一。</li>
<li><code class="docutils literal notranslate"><span class="pre">&quot;day&quot;</span></code> 返回该字段的所有不同年／月／日值的列表。</li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">order</span></code>，默认为 <code class="docutils literal notranslate"><span class="pre">'ASC'</span></code>，应该是 <code class="docutils literal notranslate"><span class="pre">'ASC'</span></code> 或 <code class="docutils literal notranslate"><span class="pre">'DESC'</span></code>。这指定了如何对结果进行排序。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">dates</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;year&#39;</span><span class="p">)</span>
<span class="go">[datetime.date(2005, 1, 1)]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">dates</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;month&#39;</span><span class="p">)</span>
<span class="go">[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">dates</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;week&#39;</span><span class="p">)</span>
<span class="go">[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">dates</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">)</span>
<span class="go">[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">dates</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">,</span> <span class="n">order</span><span class="o">=</span><span class="s1">&#39;DESC&#39;</span><span class="p">)</span>
<span class="go">[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__contains</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">dates</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">)</span>
<span class="go">[datetime.date(2005, 3, 20)]</span>
</pre></div>
</div>
</div>
<div class="section" id="s-datetimes">
<span id="datetimes"></span><h4><code class="docutils literal notranslate"><span class="pre">datetimes()</span></code><a class="headerlink" href="#datetimes" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.datetimes">
<code class="descname">datetimes</code>(<em>field_name</em>, <em>kind</em>, <em>order='ASC'</em>, <em>tzinfo=None</em>, <em>is_dst=None</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.datetimes" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，它的值是一个 <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.datetime" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.datetime</span></code></a> 对象的列表，代表 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 内容中所有可用的特定日期。</p>
<p><code class="docutils literal notranslate"><span class="pre">field_name</span></code> 应该是你的模型中 <code class="docutils literal notranslate"><span class="pre">DateTimeField</span></code> 的名称。</p>
<p><code class="docutils literal notranslate"><span class="pre">kind</span></code> 应该是 <code class="docutils literal notranslate"><span class="pre">&quot;year&quot;</span></code>、<code class="docutils literal notranslate"><span class="pre">&quot;month&quot;</span></code>、<code class="docutils literal notranslate"><span class="pre">&quot;week&quot;</span></code>、<code class="docutils literal notranslate"><span class="pre">&quot;day&quot;</span></code>、<code class="docutils literal notranslate"><span class="pre">&quot;hour&quot;</span></code>、<code class="docutils literal notranslate"><span class="pre">&quot;minute&quot;</span></code> 或 <code class="docutils literal notranslate"><span class="pre">&quot;second&quot;</span></code>。结果列表中的每个 <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.datetime" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.datetime</span></code></a> 对象都被“截断”为给定的 <code class="docutils literal notranslate"><span class="pre">type</span></code>。</p>
<p><code class="docutils literal notranslate"><span class="pre">order</span></code>，默认为 <code class="docutils literal notranslate"><span class="pre">'ASC'</span></code>，应该是 <code class="docutils literal notranslate"><span class="pre">'ASC'</span></code> 或 <code class="docutils literal notranslate"><span class="pre">'DESC'</span></code>。这指定了如何对结果进行排序。</p>
<p><code class="docutils literal notranslate"><span class="pre">tzinfo</span></code> 定义了在截断之前将日期时间转换为的时区。事实上，一个给定的日期时间根据使用的时区有不同的表示方式。这个参数必须是一个 <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.tzinfo" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.tzinfo</span></code></a> 对象。如果是 <code class="docutils literal notranslate"><span class="pre">None</span></code>，Django 会使用 <a class="reference internal" href="../../topics/i18n/timezones.html#default-current-time-zone"><span class="std std-ref">current time zone</span></a>。当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 时，它没有效果。</p>
<p><code class="docutils literal notranslate"><span class="pre">is_dst</span></code> 表示 <code class="docutils literal notranslate"><span class="pre">pytz</span></code> 是否应该解释夏令时中不存在的和含糊不清的日期。默认情况下（当 <code class="docutils literal notranslate"><span class="pre">is_dst=None</span></code>），<code class="docutils literal notranslate"><span class="pre">pytz</span></code> 会对这种日期时间产生异常。</p>
<div class="versionadded">
<span class="title">New in Django 3.1:</span> <p>增加了 <code class="docutils literal notranslate"><span class="pre">is_dst</span></code> 参数。</p>
</div>
<div class="admonition note" id="database-time-zone-definitions">
<p class="first admonition-title">注解</p>
<p>这个函数直接在数据库中执行时区转换。因此，你的数据库必须能够解释 <code class="docutils literal notranslate"><span class="pre">tzinfo.tzname(None)</span></code> 的值。这就转化为以下要求：</p>
<ul class="last simple">
<li>SQLite：无要求。在 Python 中使用 <a class="reference external" href="http://pytz.sourceforge.net/">pytz</a> （安装 Django 时安装）进行转换。</li>
<li>PostgreSQL：无要求（见 <a class="reference external" href="https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-TIMEZONES">Time Zones</a> ）。</li>
<li>Oracle：无要求（见 <a class="reference external" href="https://docs.oracle.com/en/database/oracle/oracle-database/18/nlspg/datetime-data-types-and-time-zone-support.html#GUID-805AB986-DE12-4FEA-AF56-5AABCD2132DF">Choosing a Time Zone File</a> ）。</li>
<li>MySQL：用 <a class="reference external" href="https://dev.mysql.com/doc/refman/en/mysql-tzinfo-to-sql.html">mysql_tzinfo_to_sql</a> 加载时区表。</li>
</ul>
</div>
</div>
<div class="section" id="s-none">
<span id="none"></span><h4><code class="docutils literal notranslate"><span class="pre">none()</span></code><a class="headerlink" href="#none" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.none">
<code class="descname">none</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.none" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>Calling <code class="docutils literal notranslate"><span class="pre">none()</span></code> will create a queryset that never returns any objects and no
query will be executed when accessing the results. A <code class="docutils literal notranslate"><span class="pre">qs.none()</span></code> queryset
is an instance of <code class="docutils literal notranslate"><span class="pre">EmptyQuerySet</span></code>.</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">none</span><span class="p">()</span>
<span class="go">&lt;QuerySet []&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models.query</span> <span class="kn">import</span> <span class="n">EmptyQuerySet</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">none</span><span class="p">(),</span> <span class="n">EmptyQuerySet</span><span class="p">)</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="s-all">
<span id="all"></span><h4><code class="docutils literal notranslate"><span class="pre">all()</span></code><a class="headerlink" href="#all" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.all">
<code class="descname">all</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.all" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回当前 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> （或 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 子类）的 <em>副本</em>。 这在以下情况下很有用：你可能想传入一个模型管理器或一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，并对结果做进一步过滤。在任何一个对象上调用 <code class="docutils literal notranslate"><span class="pre">all()</span></code> 后，你肯定会有一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 可以使用。</p>
<p>当一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 被 <a class="reference internal" href="#when-querysets-are-evaluated"><span class="std std-ref">执行</span></a> 时，它通常会缓存其结果。如果数据库中的数据可能在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 被评估后发生了变化，你可以通过调用 <code class="docutils literal notranslate"><span class="pre">all()</span></code> 对以前执行过的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 进行更新。</p>
</div>
<div class="section" id="s-union">
<span id="union"></span><h4><code class="docutils literal notranslate"><span class="pre">union()</span></code><a class="headerlink" href="#union" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.union">
<code class="descname">union</code>(<em>*other_qs</em>, <em>all=False</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.union" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>使用 SQL 的 <code class="docutils literal notranslate"><span class="pre">UNION</span></code> 操作符来组合两个或多个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的结果。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs1</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">qs2</span><span class="p">,</span> <span class="n">qs3</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">UNION</span></code> 操作符默认只选择不同的值。要允许重复的值，使用 <code class="docutils literal notranslate"><span class="pre">all=True</span></code> 参数。</p>
<p><code class="docutils literal notranslate"><span class="pre">union()</span></code>、<code class="docutils literal notranslate"><span class="pre">intersection()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">difference()</span></code> 返回第一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 类型的模型实例，即使参数是其他模型的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>。只要 <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 列表在所有 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中都是一样的（至少是类型，只要类型顺序相同，名字就不重要），传递不同的模型就可以。在这种情况下，你必须使用第一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的列名，在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 方法中应用到结果的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs1</span> <span class="o">=</span> <span class="n">Author</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs2</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;headline&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs1</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">qs2</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>In addition, only <code class="docutils literal notranslate"><span class="pre">LIMIT</span></code>, <code class="docutils literal notranslate"><span class="pre">OFFSET</span></code>, <code class="docutils literal notranslate"><span class="pre">COUNT(*)</span></code>, <code class="docutils literal notranslate"><span class="pre">ORDER</span> <span class="pre">BY</span></code>, and
specifying columns (i.e. slicing, <a class="reference internal" href="#django.db.models.query.QuerySet.count" title="django.db.models.query.QuerySet.count"><code class="xref py py-meth docutils literal notranslate"><span class="pre">count()</span></code></a>, <a class="reference internal" href="#django.db.models.query.QuerySet.exists" title="django.db.models.query.QuerySet.exists"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exists()</span></code></a>,
<a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a>, and <a class="reference internal" href="#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a>/<a class="reference internal" href="#django.db.models.query.QuerySet.values_list" title="django.db.models.query.QuerySet.values_list"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values_list()</span></code></a>) are allowed
on the resulting <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>. Further, databases place restrictions on
what operations are allowed in the combined queries. For example, most
databases don't allow <code class="docutils literal notranslate"><span class="pre">LIMIT</span></code> or <code class="docutils literal notranslate"><span class="pre">OFFSET</span></code> in the combined queries.</p>
</div>
<div class="section" id="s-intersection">
<span id="intersection"></span><h4><code class="docutils literal notranslate"><span class="pre">intersection()</span></code><a class="headerlink" href="#intersection" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.intersection">
<code class="descname">intersection</code>(<em>*other_qs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.intersection" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>使用 SQL 的 <code class="docutils literal notranslate"><span class="pre">INTERSECT</span></code> 操作符来返回两个或多个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的共享元素。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs1</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">qs2</span><span class="p">,</span> <span class="n">qs3</span><span class="p">)</span>
</pre></div>
</div>
<p>一些限制见 <a class="reference internal" href="#django.db.models.query.QuerySet.union" title="django.db.models.query.QuerySet.union"><code class="xref py py-meth docutils literal notranslate"><span class="pre">union()</span></code></a>。</p>
</div>
<div class="section" id="s-difference">
<span id="difference"></span><h4><code class="docutils literal notranslate"><span class="pre">difference()</span></code><a class="headerlink" href="#difference" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.difference">
<code class="descname">difference</code>(<em>*other_qs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.difference" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>使用 SQL 的 <code class="docutils literal notranslate"><span class="pre">EXCEPT</span></code> 操作符，只保留存在于 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的元素，而不保留在其他 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的元素。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs1</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">qs2</span><span class="p">,</span> <span class="n">qs3</span><span class="p">)</span>
</pre></div>
</div>
<p>一些限制见 <a class="reference internal" href="#django.db.models.query.QuerySet.union" title="django.db.models.query.QuerySet.union"><code class="xref py py-meth docutils literal notranslate"><span class="pre">union()</span></code></a>。</p>
</div>
<div class="section" id="s-select-related">
<span id="select-related"></span><h4><code class="docutils literal notranslate"><span class="pre">select_related()</span></code><a class="headerlink" href="#select-related" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.select_related">
<code class="descname">select_related</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.select_related" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，它将“跟随”外键关系，在执行查询时选择额外的相关对象数据。这是一个性能提升器，它导致一个更复杂的单一查询，但意味着以后使用外键关系将不需要数据库查询。</p>
<p>下面的例子说明了普通查找和 <code class="docutils literal notranslate"><span class="pre">select_related()</span></code> 查找之间的区别。下面是标准的查询：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Hits the database.</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>

<span class="c1"># Hits the database again to get the related Blog object.</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">blog</span>
</pre></div>
</div>
<p>这里是 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 查找：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Hits the database.</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>

<span class="c1"># Doesn&#39;t hit the database, because e.blog has been prepopulated</span>
<span class="c1"># in the previous query.</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">blog</span>
</pre></div>
</div>
<p>你可以使用 <code class="docutils literal notranslate"><span class="pre">select_related()</span></code> 来处理任何对象的查询集：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">timezone</span>

<span class="c1"># Find all the blogs with entries scheduled to be published in the future.</span>
<span class="n">blogs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>

<span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__gt</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">())</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">):</span>
    <span class="c1"># Without select_related(), this would make a database query for each</span>
    <span class="c1"># loop iteration in order to fetch the related blog for each entry.</span>
    <span class="n">blogs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">blog</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">filter()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">select_related()</span></code> 的顺序并不重要。这些查询集相当于：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__gt</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">())</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;blog&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__gt</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
</pre></div>
</div>
<p>你可以用类似于查询外键的方式来跟踪外键。如果你有以下模型：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">City</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="c1"># ...</span>
    <span class="k">pass</span>

<span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="c1"># ...</span>
    <span class="n">hometown</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span>
        <span class="n">City</span><span class="p">,</span>
        <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">SET_NULL</span><span class="p">,</span>
        <span class="n">blank</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
        <span class="n">null</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
    <span class="p">)</span>

<span class="k">class</span> <span class="nc">Book</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="c1"># ...</span>
    <span class="n">author</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Person</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
</pre></div>
</div>
<p>...然后调用 <code class="docutils literal notranslate"><span class="pre">Book.objects.select_related('author__hometown').get(id=4)</span></code> 将缓存相关的 <code class="docutils literal notranslate"><span class="pre">Person</span></code> <em>和</em> 相关的 <code class="docutils literal notranslate"><span class="pre">City</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Hits the database with joins to the author and hometown tables.</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">Book</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;author__hometown&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">author</span>         <span class="c1"># Doesn&#39;t hit the database.</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">hometown</span>       <span class="c1"># Doesn&#39;t hit the database.</span>

<span class="c1"># Without select_related()...</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">Book</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>  <span class="c1"># Hits the database.</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">author</span>         <span class="c1"># Hits the database.</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">hometown</span>       <span class="c1"># Hits the database.</span>
</pre></div>
</div>
<p>你可以在传递给 <code class="docutils literal notranslate"><span class="pre">select_related()</span></code> 的字段列表中引用任何 <a class="reference internal" href="fields.html#django.db.models.ForeignKey" title="django.db.models.ForeignKey"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForeignKey</span></code></a> 或 <a class="reference internal" href="fields.html#django.db.models.OneToOneField" title="django.db.models.OneToOneField"><code class="xref py py-class docutils literal notranslate"><span class="pre">OneToOneField</span></code></a> 关系。</p>
<p>你也可以在传递给 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 的字段列表中引用一个 <a class="reference internal" href="fields.html#django.db.models.OneToOneField" title="django.db.models.OneToOneField"><code class="xref py py-class docutils literal notranslate"><span class="pre">OneToOneField</span></code></a> 的反方向——也就是说，你可以遍历一个 <a class="reference internal" href="fields.html#django.db.models.OneToOneField" title="django.db.models.OneToOneField"><code class="xref py py-class docutils literal notranslate"><span class="pre">OneToOneField</span></code></a> 回到定义字段的对象上。不指定字段名，而是使用 <a class="reference internal" href="fields.html#django.db.models.ForeignKey.related_name" title="django.db.models.ForeignKey.related_name"><code class="xref py py-attr docutils literal notranslate"><span class="pre">related_name</span></code></a> 作为相关对象上的字段。</p>
<p>在某些情况下，你可能希望调用 <code class="docutils literal notranslate"><span class="pre">select_related()</span></code> 来处理很多相关对象，或者你不知道所有的关系。在这些情况下，我们可以调用 <code class="docutils literal notranslate"><span class="pre">select_related()</span></code>，但不使用参数。这将跟随它能找到的所有非空的外键——必须指定可空的外键。在大多数情况下，不建议这样做，因为这可能会使基础查询变得更加复杂，并返回比实际需要的更多数据。</p>
<p>如果你需要清除过去调用 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 上添加的相关字段列表，你可以传递 <code class="docutils literal notranslate"><span class="pre">None</span></code> 作为参数：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">without_relations</span> <span class="o">=</span> <span class="n">queryset</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>链式调用 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 的工作方式与其他方法类似，即 <code class="docutils literal notranslate"><span class="pre">select_related('foo',</span> <span class="pre">'bar')</span></code> 等同于 <code class="docutils literal notranslate"><span class="pre">select_related('foo').select_related('bar')</span></code>。</p>
</div>
<div class="section" id="s-prefetch-related">
<span id="prefetch-related"></span><h4><code class="docutils literal notranslate"><span class="pre">prefetch_related()</span></code><a class="headerlink" href="#prefetch-related" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.prefetch_related">
<code class="descname">prefetch_related</code>(<em>*lookups</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.prefetch_related" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，它将在一个批次中自动检索每个指定查询的相关对象。</p>
<p>这与 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 有类似的目的，二者都是为了阻止因访问相关对象而引起的数据库查询潮，但策略却完全不同。</p>
<p><code class="docutils literal notranslate"><span class="pre">select_related</span></code> 的工作方式是创建一个 SQL 连接，并在 <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 语句中包含相关对象的字段。出于这个原因，<code class="docutils literal notranslate"><span class="pre">select_related</span></code> 在同一个数据库查询中得到相关对象。然而，为了避免因跨越“many”关系进行连接而产生更大的结果集，<code class="docutils literal notranslate"><span class="pre">select_related</span></code> 仅限于单值关系——外键和一对一。</p>
<p><code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 则对每个关系进行单独的查找，并在 Python 中进行“joining”。这使得它除了支持 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 的外键和一对一关系外，还可以预取多对多和多对一的对象，这是用 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 无法做到的。它还支持 <code class="xref py py-class docutils literal notranslate"><span class="pre">GenericRelation</span></code> 和 <code class="xref py py-class docutils literal notranslate"><span class="pre">GenericForeignKey</span></code> 的预取，但是，它必须限制在一组同质的结果中。例如，只有当查询仅限于一个 <code class="docutils literal notranslate"><span class="pre">ContentType</span></code> 时，才支持预取 <code class="docutils literal notranslate"><span class="pre">GenericForeignKey</span></code> 引用的对象。</p>
<p>例如，假设你有这些模型：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Topping</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Pizza</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span>
    <span class="n">toppings</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ManyToManyField</span><span class="p">(</span><span class="n">Topping</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
            <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">topping</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">topping</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">all</span><span class="p">()),</span>
        <span class="p">)</span>
</pre></div>
</div>
<p>并运行：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">[&quot;Hawaiian (ham, pineapple)&quot;, &quot;Seafood (prawns, smoked salmon)&quot;...</span>
</pre></div>
</div>
<p>这样做的问题是，每次 <code class="docutils literal notranslate"><span class="pre">Pizza.__str__()</span></code> 要求 <code class="docutils literal notranslate"><span class="pre">self.toppings.all()</span></code> 都要查询数据库，所以 <code class="docutils literal notranslate"><span class="pre">Pizza.objects.all()</span></code> 会在 Toppings 表上对 Pizza <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的 <em>每</em> 项进行查询。</p>
<p>我们可以使用 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 减少到只有两个查询：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;toppings&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>这意味着每一个 <code class="docutils literal notranslate"><span class="pre">Pizza</span></code> 都有一个 <code class="docutils literal notranslate"><span class="pre">self.toppings.all()</span></code>；现在每次调用 <code class="docutils literal notranslate"><span class="pre">self.toppings.all()</span></code> 时，不必再去数据库中寻找这些项目，而是在一次查询中填充的预设 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 缓存中找到它们。</p>
<p>也就是说，所有相关的顶点都将在一次查询中被获取，并被用来制作 <code class="docutils literal notranslate"><span class="pre">QuerySets</span></code>，其中有一个预先填充的相关结果的缓存；然后这些 <code class="docutils literal notranslate"><span class="pre">QuerySets</span></code> 被用于 <code class="docutils literal notranslate"><span class="pre">self.toppings.all()</span></code> 的调用。</p>
<p><code class="docutils literal notranslate"><span class="pre">prefetch_related()</span></code> 中的附加查询是在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 开始执行和主要查询被执行后执行的。</p>
<p>如果你有一个作为模型实例的可迭代对象，你可以使用 <a class="reference internal" href="#django.db.models.prefetch_related_objects" title="django.db.models.prefetch_related_objects"><code class="xref py py-func docutils literal notranslate"><span class="pre">prefetch_related_objects()</span></code></a> 函数在这些实例上预取相关属性。</p>
<p>请注意，主 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的结果缓存和所有指定的相关对象将被完全加载到内存中。这改变了 <code class="docutils literal notranslate"><span class="pre">QuerySets</span></code> 的典型行为，它通常试图避免在需要之前将所有对象加载到内存中，即使在数据库中执行了一个查询之后。</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>请记住，与 <code class="docutils literal notranslate"><span class="pre">QuerySets</span></code> 一样，任何后续的链式方法，如果意味着不同的数据库查询，将忽略之前缓存的结果，并使用新的数据库查询来检索数据。所以，如果你写了以下内容：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">pizzas</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;toppings&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">[</span><span class="nb">list</span><span class="p">(</span><span class="n">pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">spicy</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span> <span class="k">for</span> <span class="n">pizza</span> <span class="ow">in</span> <span class="n">pizzas</span><span class="p">]</span>
</pre></div>
</div>
<p>...那么 <code class="docutils literal notranslate"><span class="pre">pizza.toppings.all()</span></code> 已经被预取的事实对你没有帮助。<code class="docutils literal notranslate"><span class="pre">prefetch_related('toppings')</span></code> 意味着 <code class="docutils literal notranslate"><span class="pre">pizza.toppings.all()</span></code>，但 <code class="docutils literal notranslate"><span class="pre">pizza.toppings.filter()</span></code> 是一个新的、不同的查询。预设缓存在这里帮不上忙，事实上它损害了性能，因为你做了一个你没有使用过的数据库查询。所以要谨慎使用这个功能！</p>
<p class="last">另外，如果你调用了 <code class="xref py py-meth docutils literal notranslate"><span class="pre">add()</span></code>、<code class="xref py py-meth docutils literal notranslate"><span class="pre">remove()</span></code>、<code class="xref py py-meth docutils literal notranslate"><span class="pre">clear()</span></code> 或 <code class="xref py py-meth docutils literal notranslate"><span class="pre">set()</span></code>，在 <code class="xref py py-class docutils literal notranslate"><span class="pre">related</span> <span class="pre">managers</span></code> 上，关系的任何预取缓存将被清除。</p>
</div>
<p>你也可以用普通的 join 语法来做相关字段的相关字段。假设我们在上面的例子中多了一个模型：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Restaurant</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">pizzas</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ManyToManyField</span><span class="p">(</span><span class="n">Pizza</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s1">&#39;restaurants&#39;</span><span class="p">)</span>
    <span class="n">best_pizza</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Pizza</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s1">&#39;championed_by&#39;</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
</pre></div>
</div>
<p>以下都是合法的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>这将预取所有属于餐馆的披萨，以及所有属于这些披萨的配料。这将导致总共 3 个数据库查询——一个查询餐厅，一个查询披萨，一个查询配料。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;best_pizza__toppings&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>这将为每家餐厅获取最好的比萨饼和最好的比萨饼的所有配料。这将在 3 个数据库查询中完成——一个查询餐厅，一个查询“最佳披萨”，一个查询配料。</p>
<p><code class="docutils literal notranslate"><span class="pre">best_pizza</span></code> 关系也可以用 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 来获取，将查询次数减少到 2：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;best_pizza&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;best_pizza__toppings&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>由于预取是在主查询之后执行的（其中包括 <code class="docutils literal notranslate"><span class="pre">select_related</span></code> 所需要的连接），它能够检测到 <code class="docutils literal notranslate"><span class="pre">best_pizza</span></code> 对象已经被取走了，它将跳过再次取走它们。</p>
<p>链式调用 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 将累积预取的查找。要清除任何 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 行为，传递 <code class="docutils literal notranslate"><span class="pre">None</span></code> 作为参数：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">non_prefetched</span> <span class="o">=</span> <span class="n">qs</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>在使用 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 时，需要注意的一个区别是，查询创建的对象可以在与其相关的不同对象之间共享，即一个 Python 模型实例可以出现在返回的对象树的多个点上。这通常会发生在外键关系中。通常情况下，这种行为不会有问题，而且事实上会节省内存和 CPU 时间。</p>
<p>虽然 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 支持预取 <code class="docutils literal notranslate"><span class="pre">GenericForeignKey</span></code> 关系，但查询次数将取决于数据。由于一个 <code class="docutils literal notranslate"><span class="pre">GenericForeignKey</span></code> 可以引用多个表中的数据，所以需要对每个被引用的表进行一次查询，而不是对所有项目进行一次查询。如果还没有获取相关的行，可以对 <code class="docutils literal notranslate"><span class="pre">ContentType</span></code> 表进行额外的查询。</p>
<p><code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 在大多数情况下，将使用使用“IN”操作符的 SQL 查询来实现。这意味着对于一个大的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 可能会生成一个大的“IN”子句，这取决于数据库，在解析或执行 SQL 查询时可能会有自己的性能问题。一定要针对自己的用例进行剖析！</p>
<p>请注意，如果你使用 <code class="docutils literal notranslate"><span class="pre">iterator()</span></code> 来运行查询，<code class="docutils literal notranslate"><span class="pre">prefetch_related()</span></code> 的调用将被忽略，因为这两个优化在一起没有意义。</p>
<p>你可以使用 <a class="reference internal" href="#django.db.models.Prefetch" title="django.db.models.Prefetch"><code class="xref py py-class docutils literal notranslate"><span class="pre">Prefetch</span></code></a> 对象来进一步控制预取操作。</p>
<p>最简单的形式 <code class="docutils literal notranslate"><span class="pre">Prefetch</span></code> 相当于传统的基于字符串的查找。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Prefetch</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">))</span>
</pre></div>
</div>
<p>你可以用可选的 <code class="docutils literal notranslate"><span class="pre">queryset</span></code> 参数提供一个自定义查询集。这可以用来改变查询集的默认排序。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">Toppings</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)))</span>
</pre></div>
</div>
<p>或者在适用的时候调用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code>，以进一步减少查询次数。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;restaurants&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;best_pizza&#39;</span><span class="p">)))</span>
</pre></div>
</div>
<p>你也可以用可选的 <code class="docutils literal notranslate"><span class="pre">to_attr</span></code> 参数将预取结果分配给一个自定义属性。结果将直接存储在一个列表中。</p>
<p>这允许用不同的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 预取同一关系多次；例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">vegetarian_pizzas</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">vegetarian</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">to_attr</span><span class="o">=</span><span class="s1">&#39;menu&#39;</span><span class="p">),</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">vegetarian_pizzas</span><span class="p">,</span> <span class="n">to_attr</span><span class="o">=</span><span class="s1">&#39;vegetarian_menu&#39;</span><span class="p">))</span>
</pre></div>
</div>
<p>使用自定义 <code class="docutils literal notranslate"><span class="pre">to_attr</span></code> 创建的查找仍然可以像往常一样被其他查找遍历。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">vegetarian_pizzas</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">vegetarian</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">vegetarian_pizzas</span><span class="p">,</span> <span class="n">to_attr</span><span class="o">=</span><span class="s1">&#39;vegetarian_menu&#39;</span><span class="p">),</span>
<span class="gp">... </span>    <span class="s1">&#39;vegetarian_menu__toppings&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>在对预取结果进行过滤时，建议使用 <code class="docutils literal notranslate"><span class="pre">to_attr</span></code>，因为它比将过滤后的结果存储在相关管理器的缓存中更不含糊。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">queryset</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">vegetarian</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">&gt;&gt;&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Recommended:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">restaurants</span> <span class="o">=</span> <span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">queryset</span><span class="p">,</span> <span class="n">to_attr</span><span class="o">=</span><span class="s1">&#39;vegetarian_pizzas&#39;</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">vegetarian_pizzas</span> <span class="o">=</span> <span class="n">restaurants</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">vegetarian_pizzas</span>
<span class="go">&gt;&gt;&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Not recommended:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">restaurants</span> <span class="o">=</span> <span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">queryset</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">vegetarian_pizzas</span> <span class="o">=</span> <span class="n">restaurants</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">pizzas</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>
</div>
<p>自定义预取也适用于单一的相关关系，如前向 <code class="docutils literal notranslate"><span class="pre">ForeignKey</span></code> 或 <code class="docutils literal notranslate"><span class="pre">OneToOneField</span></code>。一般来说，你会希望使用 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 来处理这些关系，但在一些情况下，使用自定义 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 进行预取是有用的。</p>
<ul>
<li><p class="first">你要使用一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，对相关模型进行进一步的预取。</p>
</li>
<li><p class="first">你想只预取相关对象的一个子集。</p>
</li>
<li><p class="first">你要使用性能优化技术，比如 <a class="reference internal" href="#django.db.models.query.QuerySet.defer" title="django.db.models.query.QuerySet.defer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">递延字段</span></code></a>。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">queryset</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">only</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span>
<span class="go">&gt;&gt;&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">restaurants</span> <span class="o">=</span> <span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;best_pizza&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">queryset</span><span class="p">))</span>
</pre></div>
</div>
</li>
</ul>
<p>当使用多个数据库时，<code class="docutils literal notranslate"><span class="pre">Prefetch</span></code> 将尊重你对数据库的选择。如果内部查询没有指定数据库，它将使用外部查询选择的数据库。以下所有情况都是有效的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># Both inner and outer queries will use the &#39;replica&#39; database</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="s1">&#39;replica&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">),</span>
<span class="gp">... </span><span class="p">)</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="s1">&#39;replica&#39;</span><span class="p">)</span>
<span class="go">&gt;&gt;&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Inner will use the &#39;replica&#39; database; outer will use &#39;default&#39; database</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">Toppings</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="s1">&#39;replica&#39;</span><span class="p">)),</span>
<span class="gp">... </span><span class="p">)</span>
<span class="go">&gt;&gt;&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Inner will use &#39;replica&#39; database; outer will use &#39;cold-storage&#39; database</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">Toppings</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="s1">&#39;replica&#39;</span><span class="p">)),</span>
<span class="gp">... </span><span class="p">)</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="s1">&#39;cold-storage&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>查询的顺序很重要。</p>
<p>下面举例说明：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">,</span> <span class="s1">&#39;pizzas&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>即使它是无序的，这也是可行的，因为 <code class="docutils literal notranslate"><span class="pre">'pizzas__toppings'</span></code> 已经包含了所有需要的信息，因此第二个参数 <code class="docutils literal notranslate"><span class="pre">'pizzas'</span></code> 实际上是多余的。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">,</span> <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">Pizza</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()))</span>
</pre></div>
</div>
<p>这将引发一个 <code class="docutils literal notranslate"><span class="pre">ValueError</span></code>，因为它试图重新定义一个先前看到的查询的查询集。请注意，一个隐式查询集被创建为遍历 <code class="docutils literal notranslate"><span class="pre">''pizzas'</span></code> 作为 <code class="docutils literal notranslate"><span class="pre">''pizzas__toppings'</span></code> 查询的一部分。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">prefetch_related</span><span class="p">(</span><span class="s1">&#39;pizza_list__toppings&#39;</span><span class="p">,</span> <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">to_attr</span><span class="o">=</span><span class="s1">&#39;pizza_list&#39;</span><span class="p">))</span>
</pre></div>
</div>
<p>这将触发一个 <code class="docutils literal notranslate"><span class="pre">AttributeError</span></code>，因为 <code class="docutils literal notranslate"><span class="pre">'pizza_list'</span></code> 在处理 <code class="docutils literal notranslate"><span class="pre">'pizza_list__toppings'</span></code> 时还不存在。</p>
<p class="last">这种考虑不限于使用 <code class="docutils literal notranslate"><span class="pre">Prefetch</span></code> 对象。一些高级技术可能要求按照特定的顺序进行查找，以避免产生额外的查询；因此，建议总是仔细地安排 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 参数的顺序。</p>
</div>
</div>
<div class="section" id="s-extra">
<span id="extra"></span><h4><code class="docutils literal notranslate"><span class="pre">extra()</span></code><a class="headerlink" href="#extra" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.extra">
<code class="descname">extra</code>(<em>select=None</em>, <em>where=None</em>, <em>params=None</em>, <em>tables=None</em>, <em>order_by=None</em>, <em>select_params=None</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.extra" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>有时候，Django 查询语法本身并不能很容易地表达一个复杂的 <code class="docutils literal notranslate"><span class="pre">WHERE</span></code> 子句。对于这些边缘情况，Django 提供了 <code class="docutils literal notranslate"><span class="pre">extra()</span></code> <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 修饰符——用于将特定的子句注入到由 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 生成的 SQL 中。</p>
<div class="admonition-use-this-method-as-a-last-resort admonition">
<p class="first admonition-title">在万不得已的情况下使用这种方法</p>
<p>这是一个老的 API，我们的目标是在未来的某个时间点废弃。只有当你不能使用其他的查询集方法来表达你的查询时才使用它。如果你确实需要使用它，请使用 <a class="reference external" href="https://code.djangoproject.com/query?status=assigned&amp;status=new&amp;keywords=~QuerySet.extra">QuerySet.extra keyword</a> 并和你的用例（请先检查现有的工单列表）一起 <a class="reference external" href="https://code.djangoproject.com/newticket">file a ticket</a> ，这样我们就可以增强 QuerySet API 以允许删除 <code class="docutils literal notranslate"><span class="pre">extra()</span></code>。我们不再改进或修复该方法的错误。</p>
<p>例如，<code class="docutils literal notranslate"><span class="pre">extra()</span></code> 的这种用法：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">select</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;val&#39;</span><span class="p">:</span> <span class="s2">&quot;select col from sometable where othercol = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">},</span>
<span class="gp">... </span>    <span class="n">select_params</span><span class="o">=</span><span class="p">(</span><span class="n">someparam</span><span class="p">,),</span>
<span class="gp">... </span><span class="p">)</span>
</pre></div>
</div>
<p>相当于：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">val</span><span class="o">=</span><span class="n">RawSQL</span><span class="p">(</span><span class="s2">&quot;select col from sometable where othercol = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">someparam</span><span class="p">,)))</span>
</pre></div>
</div>
<p class="last">使用 <a class="reference internal" href="expressions.html#django.db.models.expressions.RawSQL" title="django.db.models.expressions.RawSQL"><code class="xref py py-class docutils literal notranslate"><span class="pre">RawSQL</span></code></a> 的主要好处是，如果需要的话，可以设置 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>。主要的缺点是，如果你在原始 SQL 中引用了查询集的某个表的别名，那么 Django 有可能会改变这个别名（例如，当查询集在另一个查询中被用作子查询时）。</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p>每当你使用 <code class="docutils literal notranslate"><span class="pre">extra()</span></code> 时，你应该非常小心。每次使用它时，你应该使用 <code class="docutils literal notranslate"><span class="pre">params</span></code> 来转义任何用户可以控制的参数，以防止 SQL 注入攻击。</p>
<p>你也不能在 SQL 字符串中引用占位符。这个例子因为在 <code class="docutils literal notranslate"><span class="pre">%s</span></code> 周围的引号而容易受到 SQL 注入的影响。</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="n">col</span> <span class="k">FROM</span> <span class="n">sometable</span> <span class="k">WHERE</span> <span class="n">othercol</span> <span class="o">=</span> <span class="s1">&#39;%s&#39;</span>  <span class="o">#</span> <span class="n">unsafe</span><span class="o">!</span>
</pre></div>
</div>
<p class="last">你可以阅读更多关于 Django 的 <a class="reference internal" href="../../topics/security.html#sql-injection-protection"><span class="std std-ref">SQL 注入保护</span></a> 的工作原理。</p>
</div>
<p>根据定义，这些额外的查找可能无法移植到不同的数据库引擎中（因为你明确地编写了 SQL 代码），并且违反了 DRY 原则，所以你应该尽可能地避免它们。</p>
<p>指定 <code class="docutils literal notranslate"><span class="pre">params</span></code>、<code class="docutils literal notranslate"><span class="pre">select</span></code>、<code class="docutils literal notranslate"><span class="pre">where</span></code> 或 <code class="docutils literal notranslate"><span class="pre">tables</span></code> 中的一个或多个参数。这些参数都不是必须的，但你应该至少使用其中的一个。</p>
<ul>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">select</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">select</span></code> 参数让你在 <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 子句中放入额外的字段。 它应该是一个将属性名映射到 SQL 子句的字典，用于计算该属性。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">select</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;is_recent&#39;</span><span class="p">:</span> <span class="s2">&quot;pub_date &gt; &#39;2006-01-01&#39;&quot;</span><span class="p">})</span>
</pre></div>
</div>
<p>因此，每个 <code class="docutils literal notranslate"><span class="pre">Entry</span></code> 对象将有一个额外的属性，<code class="docutils literal notranslate"><span class="pre">is_recent</span></code>，一个布尔值，表示该条目的 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 是否大于 2006 年 1 月 1 日。</p>
<p>Django 将给定的 SQL 片段直接插入到 <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 语句中，所以上面例子的 SQL 结果将是这样的。</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="n">blog_entry</span><span class="p">.</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">pub_date</span> <span class="o">&gt;</span> <span class="s1">&#39;2006-01-01&#39;</span><span class="p">)</span> <span class="k">AS</span> <span class="n">is_recent</span>
<span class="k">FROM</span> <span class="n">blog_entry</span><span class="p">;</span>
</pre></div>
</div>
<p>下一个例子更高级；它做了一个子查询，给每个结果的 <code class="docutils literal notranslate"><span class="pre">Blog</span></code> 对象一个 <code class="docutils literal notranslate"><span class="pre">entry_count</span></code> 属性，一个相关 <code class="docutils literal notranslate"><span class="pre">Entry</span></code> 对象的整数：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span>
    <span class="n">select</span><span class="o">=</span><span class="p">{</span>
        <span class="s1">&#39;entry_count&#39;</span><span class="p">:</span> <span class="s1">&#39;SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id&#39;</span>
    <span class="p">},</span>
<span class="p">)</span>
</pre></div>
</div>
<p>在这个特殊的情况下，我们利用了这样一个事实，即查询在其 <code class="docutils literal notranslate"><span class="pre">FROM</span></code> 子句中已经包含 <code class="docutils literal notranslate"><span class="pre">blog_blog</span></code> 表。</p>
<p>上述例子的 SQL 结果是：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="n">blog_blog</span><span class="p">.</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="k">SELECT</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">blog_entry</span> <span class="k">WHERE</span> <span class="n">blog_entry</span><span class="p">.</span><span class="n">blog_id</span> <span class="o">=</span> <span class="n">blog_blog</span><span class="p">.</span><span class="n">id</span><span class="p">)</span> <span class="k">AS</span> <span class="n">entry_count</span>
<span class="k">FROM</span> <span class="n">blog_blog</span><span class="p">;</span>
</pre></div>
</div>
<p>需要注意的是，大多数数据库引擎要求在子查询周围加上括号，而 Django 的 <code class="docutils literal notranslate"><span class="pre">select</span></code> 子句则不需要。还需要注意的是，一些数据库后端，比如一些 MySQL 版本，不支持子查询。</p>
<p>在一些罕见的情况下，你可能希望在 <code class="docutils literal notranslate"><span class="pre">extra(select=...)</span></code> 中给 SQL 片段传递参数。为此，使用 <code class="docutils literal notranslate"><span class="pre">select_params</span></code> 参数。</p>
<p>这样做就可以了，比如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span>
    <span class="n">select</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;a&#39;</span><span class="p">:</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;b&#39;</span><span class="p">:</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">},</span>
    <span class="n">select_params</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;one&#39;</span><span class="p">,</span> <span class="s1">&#39;two&#39;</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>如果你需要在选择字符串中使用 <code class="docutils literal notranslate"><span class="pre">%s</span></code>，请使用序列 <code class="docutils literal notranslate"><span class="pre">%%s</span></code>。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">where</span></code>／<code class="docutils literal notranslate"><span class="pre">tables</span></code></p>
<p>你可以通过使用 <code class="docutils literal notranslate"><span class="pre">where</span></code> 来定义明确的 SQL <code class="docutils literal notranslate"><span class="pre">WHERE</span></code> 子句——也许是为了执行非明确的连接。你可以通过使用 <code class="docutils literal notranslate"><span class="pre">tables</span></code> 手动添加表到 SQL <code class="docutils literal notranslate"><span class="pre">FROM</span></code> 子句中。</p>
<p><code class="docutils literal notranslate"><span class="pre">where</span></code> 和 <code class="docutils literal notranslate"><span class="pre">tables</span></code> 都采用一个字符串列表。所有 <code class="docutils literal notranslate"><span class="pre">where</span></code> 参数都与任何其他搜索标准“AND”在一起。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">where</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;foo=&#39;a&#39; OR bar = &#39;a&#39;&quot;</span><span class="p">,</span> <span class="s2">&quot;baz = &#39;a&#39;&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>...翻译成（大致）下面的 SQL：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">blog_entry</span> <span class="k">WHERE</span> <span class="p">(</span><span class="n">foo</span><span class="o">=</span><span class="s1">&#39;a&#39;</span> <span class="k">OR</span> <span class="n">bar</span><span class="o">=</span><span class="s1">&#39;a&#39;</span><span class="p">)</span> <span class="k">AND</span> <span class="p">(</span><span class="n">baz</span><span class="o">=</span><span class="s1">&#39;a&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>如果使用 <code class="docutils literal notranslate"><span class="pre">tables</span></code> 参数时，要注意指定查询中已经使用过的表，当你通过 <code class="docutils literal notranslate"><span class="pre">tables</span></code> 参数添加额外的表时，Django 会认为你希望额外包含该表，如果已经包含的话。当你通过 <code class="docutils literal notranslate"><span class="pre">tables</span></code> 参数添加额外的表时，Django 会认为你希望额外地包含该表，如果它已经被包含了。这就会产生一个问题，因为表名会被赋予一个别名。如果一个表在一条 SQL 语句中多次出现，那么第二次和后续的表必须使用别名，这样数据库才能区分它们。如果你指的是你在额外的 <code class="docutils literal notranslate"><span class="pre">where</span></code> 参数中添加的额外表，这就会造成错误。</p>
<p>一般情况下，你只会添加查询中还没有出现的额外表。但是，如果确实出现了上面概述的情况，有几种解决办法。首先，看看是否可以不包含额外的表，而使用已经在查询中出现的表。如果不可能的话，把你的 <code class="docutils literal notranslate"><span class="pre">extra()</span></code> 调用放在查询集构造的前面，这样你的表就是那个表的第一次使用。最后，如果所有其他方法都失败了，看一下产生的查询，重写你的 <code class="docutils literal notranslate"><span class="pre">where</span></code> 加法，使用给你的额外表的别名。每次以同样的方式构造查询集时，别名都会是一样的，所以你可以信赖别名不会改变。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">order_by</span></code></p>
<p>如果你需要使用你通过 <code class="docutils literal notranslate"><span class="pre">extra()</span></code> 所包含的一些新字段或表来对结果查询集进行排序，请使用 <code class="docutils literal notranslate"><span class="pre">extra()</span></code> 的 <code class="docutils literal notranslate"><span class="pre">order_by</span></code> 参数，并传入一串字符串。这些字符串应该是模型字段（就像在查询集上的普通 <a class="reference internal" href="#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> 方法一样），形式为 <code class="docutils literal notranslate"><span class="pre">table_name.column_name</span></code> 或者是你在 <code class="docutils literal notranslate"><span class="pre">extra()</span></code> 的 <code class="docutils literal notranslate"><span class="pre">select</span></code> 参数中指定的列的别名。</p>
<p>例子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">q</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">select</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;is_recent&#39;</span><span class="p">:</span> <span class="s2">&quot;pub_date &gt; &#39;2006-01-01&#39;&quot;</span><span class="p">})</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">order_by</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;-is_recent&#39;</span><span class="p">])</span>
</pre></div>
</div>
<p>这将把 <code class="docutils literal notranslate"><span class="pre">is_recent</span></code> 为真的所有项目排在结果集的前面（<code class="docutils literal notranslate"><span class="pre">True</span></code> 按降序排列在 <code class="docutils literal notranslate"><span class="pre">False</span></code> 之前）。</p>
<p>顺便说一下，这表明你可以多次调用 <code class="docutils literal notranslate"><span class="pre">extra()</span></code>，它将按照你的期望行事（每次增加新的约束）。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">params</span></code></p>
<p>上面描述的 <code class="docutils literal notranslate"><span class="pre">where</span></code> 参数可以使用标准的 Python 数据库字符串占位符——<code class="docutils literal notranslate"><span class="pre">'%s'</span></code> 来表示数据库引擎应该自动引用的参数。<code class="docutils literal notranslate"><span class="pre">params</span></code> 参数是一个要被替换的额外参数的列表。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">where</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;headline=</span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">],</span> <span class="n">params</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;Lennon&#39;</span><span class="p">])</span>
</pre></div>
</div>
<p>始终使用 <code class="docutils literal notranslate"><span class="pre">params</span></code> 而不是直接将值嵌入 <code class="docutils literal notranslate"><span class="pre">where</span></code>，因为 <code class="docutils literal notranslate"><span class="pre">params</span></code> 将确保根据你的特定后台正确引用值。例如，引号将被正确转义。</p>
<p>不好的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">where</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;headline=&#39;Lennon&#39;&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>正确的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">where</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;headline=</span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">],</span> <span class="n">params</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;Lennon&#39;</span><span class="p">])</span>
</pre></div>
</div>
</li>
</ul>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">如果你在 MySQL 上执行查询，请注意 MySQL 的静默强制类型转换可能会在混合类型时导致意外的结果。如果你在一个字符串类型的列上查询，但却有一个整数值，MySQL 会在执行比较之前将表中所有值的类型强制转换为整数。例如，如果你的表中包含值 <code class="docutils literal notranslate"><span class="pre">'abc'</span></code>、<code class="docutils literal notranslate"><span class="pre">'def'</span></code>，而你查询 <code class="docutils literal notranslate"><span class="pre">WHERE</span> <span class="pre">mycolumn=0</span></code>，这两行都会匹配。为了防止这种情况发生，在查询中使用该值之前，请执行正确的类型转换。</p>
</div>
</div>
<div class="section" id="s-defer">
<span id="defer"></span><h4><code class="docutils literal notranslate"><span class="pre">defer()</span></code><a class="headerlink" href="#defer" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.defer">
<code class="descname">defer</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.defer" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>在一些复杂的数据建模情况下，你的模型可能包含很多字段，其中一些字段可能包含很多数据（例如，文本字段），或者需要昂贵的处理来将它们转换为 Python 对象。如果你在某些情况下使用查询集的结果，在最初获取数据时不知道是否需要这些特定的字段，你可以告诉 Django 不要从数据库中检索这些字段。</p>
<p>通过将不加载的字段名称传递给 <code class="docutils literal notranslate"><span class="pre">defer()</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;headline&quot;</span><span class="p">,</span> <span class="s2">&quot;body&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>一个有递延字段的查询集仍然会返回模型实例。如果你访问每个递延字段，将从数据库中检索该字段（一次一个，而不是同时访问所有的递延字段）。</p>
<p>你可以多次调用 <code class="docutils literal notranslate"><span class="pre">defer()</span></code>。每次调用都会在推迟的集合中增加新的字段：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Defers both the body and headline fields.</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;body&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">rating</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;headline&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>字段被添加到递延集的顺序并不重要。用已经被递延的字段名调用 <code class="docutils literal notranslate"><span class="pre">defer()</span></code> 是无害的（该字段仍将被递延）。</p>
<p>你可以通过使用标准的双下划线符号来分隔相关的字段，来推迟加载相关模型中的字段（如果相关模型是通过 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 加载的）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">()</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;entry__headline&quot;</span><span class="p">,</span> <span class="s2">&quot;entry__body&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>如果你想清除一组递延字段，将 <code class="docutils literal notranslate"><span class="pre">None</span></code> 作为参数传递给 <code class="docutils literal notranslate"><span class="pre">defer()</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Load all fields immediately.</span>
<span class="n">my_queryset</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>模型中的一些字段不会被推迟，即使你要求它们。你永远不能推迟加载主键。如果你使用 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 来检索相关的模型，你不应该推迟从主模型连接到相关模型的字段的加载，这样做会导致一个错误。</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p><code class="docutils literal notranslate"><span class="pre">defer()</span></code> 方法（和它的表兄弟 <a class="reference internal" href="#django.db.models.query.QuerySet.only" title="django.db.models.query.QuerySet.only"><code class="xref py py-meth docutils literal notranslate"><span class="pre">only()</span></code></a>，见下面）只适用于进阶使用情况。它们提供了一种优化，当你仔细分析了你的查询，了解了你所需要的 <em>确切</em> 的信息，并且测算出返回你所需要的字段和模型的全部字段集之间的差异会很大。</p>
<p>即使你认为自己处于进阶用例的情况下， <a href="#id1"><span class="problematic" id="id2">**</span></a>只有当你在查询集加载时无法确定是否需要额外的字段时，才使用 defer() ** 。如果你经常加载和使用你的数据的一个特定子集，你可以做的最好的选择是规范你的模型，并把非加载的数据放到一个单独的模型（和数据库表）中。如果由于某些原因，列 <em>必须</em> 留在一个表中，创建一个带有 <code class="docutils literal notranslate"><span class="pre">Meta.managed</span> <span class="pre">=</span> <span class="pre">False</span></code> 的模型（参见 <a class="reference internal" href="options.html#django.db.models.Options.managed" title="django.db.models.Options.managed"><code class="xref py py-attr docutils literal notranslate"><span class="pre">managed</span> <span class="pre">属性</span></code></a> 文档），其中只包含你通常需要加载的字段，并在你可能会调用 <code class="docutils literal notranslate"><span class="pre">defer()</span></code> 的地方使用它。这使得你的代码对读者来说更加明确，速度稍快，并且在 Python 过程中消耗的内存更少。</p>
<p>例如，这两种模式都使用相同的基础数据库表：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CommonlyUsedModel</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">f1</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">managed</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="n">db_table</span> <span class="o">=</span> <span class="s1">&#39;app_largetable&#39;</span>

<span class="k">class</span> <span class="nc">ManagedModel</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">f1</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
    <span class="n">f2</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">db_table</span> <span class="o">=</span> <span class="s1">&#39;app_largetable&#39;</span>

<span class="c1"># Two equivalent QuerySets:</span>
<span class="n">CommonlyUsedModel</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="n">ManagedModel</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s1">&#39;f2&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p class="last">如果很多字段需要在非托管模型中重复，最好的办法是创建一个共享字段的抽象模型，然后让非托管模型和托管模型从抽象模型中继承。</p>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">当调用 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code></a> 对有延迟字段的实例进行保存时，只有加载的字段会被保存。更多细节请参见 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code></a>。</p>
</div>
</div>
<div class="section" id="s-only">
<span id="only"></span><h4><code class="docutils literal notranslate"><span class="pre">only()</span></code><a class="headerlink" href="#only" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.only">
<code class="descname">only</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.only" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">only()</span></code> 方法与 <a class="reference internal" href="#django.db.models.query.QuerySet.defer" title="django.db.models.query.QuerySet.defer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">defer()</span></code></a> 大致相反。在检索模型时，你调用它的时候，应该调用那些 <em>不</em> 应该递延的字段。 如果你有一个模型，其中几乎所有的字段都需要递延，使用 <code class="docutils literal notranslate"><span class="pre">only()</span></code> 来指定补充的字段集可以使代码更简单。</p>
<p>假设你有一个模型，其字段为 <code class="docutils literal notranslate"><span class="pre">name</span></code>、<code class="docutils literal notranslate"><span class="pre">age</span></code> 和 <code class="docutils literal notranslate"><span class="pre">biography</span></code>。就递延字段而言，以下两个查询集是相同的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;age&quot;</span><span class="p">,</span> <span class="s2">&quot;biography&quot;</span><span class="p">)</span>
<span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">only</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>每当你调用 <code class="docutils literal notranslate"><span class="pre">only()</span></code> 时，它就会 <em>替换</em> 要立即加载的字段集。该方法的名称是记号式的：<strong>仅</strong> 那些字段被立即加载；其余的字段被推迟。因此，连续调用 <code class="docutils literal notranslate"><span class="pre">only()</span></code> 的结果是只考虑最后的字段：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># This will defer all fields except the headline.</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">only</span><span class="p">(</span><span class="s2">&quot;body&quot;</span><span class="p">,</span> <span class="s2">&quot;rating&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">only</span><span class="p">(</span><span class="s2">&quot;headline&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>由于 <code class="docutils literal notranslate"><span class="pre">defer()</span></code> 以递增的方式行事（将字段添加到递延列表中），你可以将对 <code class="docutils literal notranslate"><span class="pre">only()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">defer()</span></code> 的调用结合起来，事情就会符合逻辑：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Final result is that everything except &quot;headline&quot; is deferred.</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">only</span><span class="p">(</span><span class="s2">&quot;headline&quot;</span><span class="p">,</span> <span class="s2">&quot;body&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;body&quot;</span><span class="p">)</span>

<span class="c1"># Final result loads headline and body immediately (only() replaces any</span>
<span class="c1"># existing set of fields).</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">defer</span><span class="p">(</span><span class="s2">&quot;body&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">only</span><span class="p">(</span><span class="s2">&quot;headline&quot;</span><span class="p">,</span> <span class="s2">&quot;body&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference internal" href="#django.db.models.query.QuerySet.defer" title="django.db.models.query.QuerySet.defer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">defer()</span></code></a> 文档注释中的所有注意事项也适用于 <code class="docutils literal notranslate"><span class="pre">only()</span></code>。谨慎使用，只有在用尽其他选项后才能使用。</p>
<p>使用 <a class="reference internal" href="#django.db.models.query.QuerySet.only" title="django.db.models.query.QuerySet.only"><code class="xref py py-meth docutils literal notranslate"><span class="pre">only()</span></code></a> 和使用 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 省略请求的字段也是错误的。</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">当调用 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code></a> 对有延迟字段的实例进行保存时，只有加载的字段会被保存。更多细节请参见 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code></a>。</p>
</div>
</div>
<div class="section" id="s-using">
<span id="using"></span><h4><code class="docutils literal notranslate"><span class="pre">using()</span></code><a class="headerlink" href="#using" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.using">
<code class="descname">using</code>(<em>alias</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.using" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果你使用多个数据库，该方法用于控制 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 将针对哪个数据库进行评估。 本方法的唯一参数是数据库的别名，定义在 <a class="reference internal" href="../settings.html#std:setting-DATABASES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DATABASES</span></code></a> 中。</p>
<p>例子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># queries the database with the &#39;default&#39; alias.</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>

<span class="c1"># queries the database with the &#39;backup&#39; alias</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="s1">&#39;backup&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="s-select-for-update">
<span id="select-for-update"></span><h4><code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code><a class="headerlink" href="#select-for-update" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.select_for_update">
<code class="descname">select_for_update</code>(<em>nowait=False</em>, <em>skip_locked=False</em>, <em>of=()</em>, <em>no_key=False</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.select_for_update" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个查询集，该查询集将锁定行直到事务结束，从而在受支持的数据库上生成 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">...</span> <span class="pre">FOR</span> <span class="pre">UPDATE</span></code> SQL 语句。</p>
<p>例子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">transaction</span>

<span class="n">entries</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_for_update</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">author</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="k">with</span> <span class="n">transaction</span><span class="o">.</span><span class="n">atomic</span><span class="p">():</span>
    <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">entries</span><span class="p">:</span>
        <span class="o">...</span>
</pre></div>
</div>
<p>当查询集被执行时（这里是 <code class="docutils literal notranslate"><span class="pre">for</span> <span class="pre">entry</span> <span class="pre">in</span> <span class="pre">entries</span></code>），所有匹配的条目将被锁定，直到事务块结束，这意味着其他事务将被阻止改变或获取它们的锁。</p>
<p>通常情况下，如果另一个事务已经获得了所选行的锁，那么查询将被阻塞，直到锁被释放。如果这不是你想要的行为，调用 <code class="docutils literal notranslate"><span class="pre">select_for_update(nowait=True)</span></code>。这将使调用非阻塞。如果一个冲突的锁已经被另一个事务获取，那么当查询集被评估时，将引发 <a class="reference internal" href="../exceptions.html#django.db.DatabaseError" title="django.db.DatabaseError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DatabaseError</span></code></a>。你也可以通过使用 <code class="docutils literal notranslate"><span class="pre">select_for_update(</span> <span class="pre">skip_locked=True)</span></code> 来忽略锁定的记录。<code class="docutils literal notranslate"><span class="pre">nowait</span></code> 和 <code class="docutils literal notranslate"><span class="pre">skip_locked</span></code> 是相互排斥的，在启用这两个选项的情况下调用 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 会导致一个 <a class="reference external" href="https://docs.python.org/3/library/exceptions.html#ValueError" title="(在 Python v3.10)"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。</p>
<p>默认情况下，<code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 锁定所有被查询选择的行。例如，在 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 中指定的相关对象的行，除了查询集模型的行之外，也会被锁定。如果不希望这样，可以在 <code class="docutils literal notranslate"><span class="pre">select_for_update(of=(...))</span></code> 中使用与 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 相同的字段语法指定你要锁定的相关对象。使用 <code class="docutils literal notranslate"><span class="pre">'self'</span></code> 来表示查询集的模型。</p>
<div class="admonition-lock-parents-models-in-select-for-update-of admonition">
<p class="first admonition-title">在 <code class="docutils literal notranslate"><span class="pre">select_for_update(of=(...))</span></code> 中锁定父模型</p>
<p>如果在使用 <a class="reference internal" href="../../topics/db/models.html#multi-table-inheritance"><span class="std std-ref">多表继承</span></a> 时要锁定父模型，必须在 <code class="docutils literal notranslate"><span class="pre">of</span></code> 参数中指定父链接字段（默认为 <code class="docutils literal notranslate"><span class="pre">&lt;parent_model_name&gt;_ptr</span></code>）。例如：</p>
<div class="last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_for_update</span><span class="p">(</span><span class="n">of</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;self&#39;</span><span class="p">,</span> <span class="s1">&#39;place_ptr&#39;</span><span class="p">))</span>
</pre></div>
</div>
</div>
<p>On PostgreSQL only, you can pass <code class="docutils literal notranslate"><span class="pre">no_key=True</span></code> in order to acquire a weaker
lock, that still allows creating rows that merely reference locked rows
(through a foreign key, for example) while the lock is in place. The
PostgreSQL documentation has more details about <a class="reference external" href="https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS">row-level lock modes</a>.</p>
<p>你不能在可空的关系上使用 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;hometown&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">select_for_update</span><span class="p">()</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">django.db.utils.NotSupportedError</span>: <span class="n">FOR UPDATE cannot be applied to the nullable side of an outer join</span>
</pre></div>
</div>
<p>为了避免这种限制，如果你不关心空对象，你可以排除它们：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;hometown&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">select_for_update</span><span class="p">()</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">hometown</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
<span class="go">&lt;QuerySet [&lt;Person: ...)&gt;, ...]&gt;</span>
</pre></div>
</div>
<p>Currently, the <code class="docutils literal notranslate"><span class="pre">postgresql</span></code>, <code class="docutils literal notranslate"><span class="pre">oracle</span></code>, and <code class="docutils literal notranslate"><span class="pre">mysql</span></code> database
backends support <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code>. However, MariaDB 10.3+ supports only
the <code class="docutils literal notranslate"><span class="pre">nowait</span></code> argument and MySQL 8.0.1+ supports the <code class="docutils literal notranslate"><span class="pre">nowait</span></code>,
<code class="docutils literal notranslate"><span class="pre">skip_locked</span></code>, and <code class="docutils literal notranslate"><span class="pre">of</span></code> arguments. The <code class="docutils literal notranslate"><span class="pre">no_key</span></code> argument is supported
only on PostgreSQL.</p>
<p>Passing <code class="docutils literal notranslate"><span class="pre">nowait=True</span></code>, <code class="docutils literal notranslate"><span class="pre">skip_locked=True</span></code>, <code class="docutils literal notranslate"><span class="pre">no_key=True</span></code>, or <code class="docutils literal notranslate"><span class="pre">of</span></code> to
<code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> using database backends that do not support these
options, such as MySQL, raises a <a class="reference internal" href="../exceptions.html#django.db.NotSupportedError" title="django.db.NotSupportedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotSupportedError</span></code></a>. This
prevents code from unexpectedly blocking.</p>
<p>在支持 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">...</span> <span class="pre">FOR</span> <span class="pre">UPDATE</span></code> 的后端上，用 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 在自动提交模式下执行一个查询集是一个 <a class="reference internal" href="../exceptions.html#django.db.transaction.TransactionManagementError" title="django.db.transaction.TransactionManagementError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TransactionManagementError</span></code></a> 错误，因为在这种情况下行没有被锁定。如果允许这样做，这将促进数据损坏，并且很容易通过调用期望在一个事务之外的事务中运行的代码而引起。</p>
<p>在不支持 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">...</span> <span class="pre">FOR</span> <span class="pre">UPDATE</span></code> 的后端（比如 SQLite）使用 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 不会有任何影响。<code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">...</span> <span class="pre">FOR</span> <span class="pre">UPDATE</span></code> 不会被添加到查询中，如果 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 在自动提交模式下使用，也不会出现错误。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">虽然 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 通常在自动提交模式下会失败，但由于 <a class="reference internal" href="../../topics/testing/tools.html#django.test.TestCase" title="django.test.TestCase"><code class="xref py py-class docutils literal notranslate"><span class="pre">TestCase</span></code></a> 会自动将每个测试封装在一个事务中，因此在一个 <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> 中调用 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 甚至在 <code class="xref py py-func docutils literal notranslate"><span class="pre">atomic()`()</span></code> 块外调用 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 会（也许会出乎意料地）通过而不会引发 <code class="docutils literal notranslate"><span class="pre">TransactionManagementError</span></code>。为了正确测试 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code>，你应该使用 <a class="reference internal" href="../../topics/testing/tools.html#django.test.TransactionTestCase" title="django.test.TransactionTestCase"><code class="xref py py-class docutils literal notranslate"><span class="pre">TransactionTestCase</span></code></a>。</p>
</div>
<div class="admonition-certain-expressions-may-not-be-supported admonition">
<p class="first admonition-title">可能不支持某些表达方式</p>
<p class="last">PostgreSQL 不支持 <code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code> 与 <a class="reference internal" href="expressions.html#django.db.models.expressions.Window" title="django.db.models.expressions.Window"><code class="xref py py-class docutils literal notranslate"><span class="pre">Window</span></code></a> 表达式。</p>
</div>
<div class="versionchanged">
<span class="title">Changed in Django 3.2:</span> <p>The <code class="docutils literal notranslate"><span class="pre">no_key</span></code> argument was added.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">of</span></code> argument was allowed on MySQL 8.0.1+.</p>
</div>
</div>
<div class="section" id="s-raw">
<span id="raw"></span><h4><code class="docutils literal notranslate"><span class="pre">raw()</span></code><a class="headerlink" href="#raw" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.raw">
<code class="descname">raw</code>(<em>raw_query</em>, <em>params=()</em>, <em>translations=None</em>, <em>using=None</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.raw" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>获取一个原始 SQL 查询，执行它，并返回一个 <code class="docutils literal notranslate"><span class="pre">django.db.models.query.RawQuerySet</span></code> 实例。这个 <code class="docutils literal notranslate"><span class="pre">RawQuerySet</span></code> 实例可以像普通的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 一样进行迭代，提供对象实例。</p>
<p>更多信息请参见 <a class="reference internal" href="../../topics/db/sql.html"><span class="doc">执行原生 SQL 查询</span></a>。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last"><code class="docutils literal notranslate"><span class="pre">raw()</span></code> 总是触发一个新的查询，并且不考虑以前的过滤。因此，它通常应该从 <code class="docutils literal notranslate"><span class="pre">Manager</span></code> 或从一个新的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 实例中调用。</p>
</div>
<div class="versionchanged">
<span class="title">Changed in Django 3.2:</span> <p>The default value of the <code class="docutils literal notranslate"><span class="pre">params</span></code> argument was changed from <code class="docutils literal notranslate"><span class="pre">None</span></code> to
an empty tuple.</p>
</div>
</div>
</div>
<div class="section" id="s-operators-that-return-new-querysets">
<span id="operators-that-return-new-querysets"></span><h3>返回新 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的操作符<a class="headerlink" href="#operators-that-return-new-querysets" title="永久链接至标题">¶</a></h3>
<p>组合的查询集必须使用相同的模型。</p>
<div class="section" id="s-and">
<span id="and"></span><h4>AND（<code class="docutils literal notranslate"><span class="pre">&amp;</span></code>）<a class="headerlink" href="#and" title="永久链接至标题">¶</a></h4>
<p>使用 SQL <code class="docutils literal notranslate"><span class="pre">AND</span></code> 操作符将两个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 组合起来。</p>
<p>以下的都是相同的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">y</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
<span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Q</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">Q</span><span class="p">(</span><span class="n">y</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">x</span><span class="o">=</span><span class="mi">1</span> <span class="k">AND</span> <span class="n">y</span><span class="o">=</span><span class="mi">2</span>
</pre></div>
</div>
</div>
<div class="section" id="s-or">
<span id="or"></span><h4>OR（<code class="docutils literal notranslate"><span class="pre">|</span></code>）<a class="headerlink" href="#or" title="永久链接至标题">¶</a></h4>
<p>使用 SQL <code class="docutils literal notranslate"><span class="pre">OR</span></code> 操作符将两个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 组合起来。</p>
<p>以下的都是相同的：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">y</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
<span class="n">Model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Q</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="n">Q</span><span class="p">(</span><span class="n">y</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">x</span><span class="o">=</span><span class="mi">1</span> <span class="k">OR</span> <span class="n">y</span><span class="o">=</span><span class="mi">2</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="s-methods-that-do-not-return-querysets">
<span id="methods-that-do-not-return-querysets"></span><h3>不返回 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的方法<a class="headerlink" href="#methods-that-do-not-return-querysets" title="永久链接至标题">¶</a></h3>
<p>以下 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 方法执行 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>，并返回 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 以外的东西。</p>
<p>这些方法不使用缓存（参见 <a class="reference internal" href="../../topics/db/queries.html#caching-and-querysets"><span class="std std-ref">缓存和 QuerySet</span></a>）。相反，它们每次被调用时都会查询数据库。</p>
<div class="section" id="s-get">
<span id="get"></span><h4><code class="docutils literal notranslate"><span class="pre">get()</span></code><a class="headerlink" href="#get" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.get">
<code class="descname">get</code>(<em>*args</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.get" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回与给定的查找参数相匹配的对象，其格式应该在 <a class="reference internal" href="#id4">Field lookups</a> 中描述。你应该使用保证唯一的查询，比如主键或唯一约束中的字段。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">Q</span><span class="p">(</span><span class="n">blog</span><span class="o">=</span><span class="n">blog</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">Q</span><span class="p">(</span><span class="n">entry_number</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
<p>如果你希望一个查询集已经返回一条记录，你可以在没有任何参数的情况下使用 <code class="docutils literal notranslate"><span class="pre">get()</span></code> 来返回该行的对象：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
</pre></div>
</div>
<p>如果 <code class="docutils literal notranslate"><span class="pre">get()</span></code> 没有找到任何对象，它会引发一个 <a class="reference internal" href="class.html#django.db.models.Model.DoesNotExist" title="django.db.models.Model.DoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Model.DoesNotExist</span></code></a> 异常：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=-</span><span class="mi">999</span><span class="p">)</span> <span class="c1"># raises Entry.DoesNotExist</span>
</pre></div>
</div>
<p>如果 <code class="docutils literal notranslate"><span class="pre">get()</span></code> 发现多个对象，会引发一个 <a class="reference internal" href="class.html#django.db.models.Model.MultipleObjectsReturned" title="django.db.models.Model.MultipleObjectsReturned"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Model.MultipleObjectsReturned</span></code></a> 异常：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;A Duplicated Name&#39;</span><span class="p">)</span> <span class="c1"># raises Entry.MultipleObjectsReturned</span>
</pre></div>
</div>
<p>这两个异常类都是模型类的属性，并且特定于该模型。如果你想对不同模型的多个 <code class="docutils literal notranslate"><span class="pre">get()</span></code> 调用处理这样的异常，可以使用它们的通用基类。例如，你可以使用 <a class="reference internal" href="../exceptions.html#django.core.exceptions.ObjectDoesNotExist" title="django.core.exceptions.ObjectDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">django.core.exceptions.ObjectDoesNotExist</span></code></a> 来处理 <code class="xref py py-exc docutils literal notranslate"><span class="pre">DoesNotExist</span></code> 来自多个模型的异常：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">ObjectDoesNotExist</span>

<span class="k">try</span><span class="p">:</span>
    <span class="n">blog</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">blog</span><span class="o">=</span><span class="n">blog</span><span class="p">,</span> <span class="n">entry_number</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ObjectDoesNotExist</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Either the blog or entry doesn&#39;t exist.&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="s-create">
<span id="create"></span><h4><code class="docutils literal notranslate"><span class="pre">create()</span></code><a class="headerlink" href="#create" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.create">
<code class="descname">create</code>(<em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.create" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>一种方便的方法，用于创建一个对象并一步到位地保存。 因此：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">p</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s2">&quot;Bruce&quot;</span><span class="p">,</span> <span class="n">last_name</span><span class="o">=</span><span class="s2">&quot;Springsteen&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>和：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">p</span> <span class="o">=</span> <span class="n">Person</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s2">&quot;Bruce&quot;</span><span class="p">,</span> <span class="n">last_name</span><span class="o">=</span><span class="s2">&quot;Springsteen&quot;</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">force_insert</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>是等效的。</p>
<p><a class="reference internal" href="instances.html#ref-models-force-insert"><span class="std std-ref">force_insert</span></a> 参数在其他地方有说明，但它的意思是总是会创建一个新的对象。通常情况下，你不需要担心这个问题。但是，如果你的模型中包含了一个你设置的手动主键值，而且如果这个值已经存在于数据库中，那么对 <code class="docutils literal notranslate"><span class="pre">create()</span></code> 的调用就会以一个 <a class="reference internal" href="../exceptions.html#django.db.IntegrityError" title="django.db.IntegrityError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">IntegrityError</span></code></a> 失败，因为主键必须是唯一的。如果使用手动主键，要做好处理异常的准备。</p>
</div>
<div class="section" id="s-get-or-create">
<span id="get-or-create"></span><h4><code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code><a class="headerlink" href="#get-or-create" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.get_or_create">
<code class="descname">get_or_create</code>(<em>defaults=None</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.get_or_create" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>一个方便的方法，用于查找具有给定 <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> 的对象（如果你的模型对所有字段都有默认值，则可能为空），必要时创建一个对象。</p>
<p>返回 <code class="docutils literal notranslate"><span class="pre">(object,</span> <span class="pre">created)</span></code> 的元组，其中 <code class="docutils literal notranslate"><span class="pre">object</span></code> 是检索或创建的对象，<code class="docutils literal notranslate"><span class="pre">created</span></code> 是指定是否创建新对象的布尔值。</p>
<p>这是为了防止在并行进行请求时创建重复的对象，并作为样板代码的快捷方式。 例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;John&#39;</span><span class="p">,</span> <span class="n">last_name</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
<span class="k">except</span> <span class="n">Person</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="n">Person</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;John&#39;</span><span class="p">,</span> <span class="n">last_name</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">,</span> <span class="n">birthday</span><span class="o">=</span><span class="n">date</span><span class="p">(</span><span class="mi">1940</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">9</span><span class="p">))</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
<p>在这里，如果是并发请求，可能会多次尝试用相同的参数保存一个 <code class="docutils literal notranslate"><span class="pre">Person</span></code>。为了避免这种竞争条件，可以使用 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 重写上面的例子，比如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">obj</span><span class="p">,</span> <span class="n">created</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span>
    <span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;John&#39;</span><span class="p">,</span>
    <span class="n">last_name</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">,</span>
    <span class="n">defaults</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;birthday&#39;</span><span class="p">:</span> <span class="n">date</span><span class="p">(</span><span class="mi">1940</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">9</span><span class="p">)},</span>
<span class="p">)</span>
</pre></div>
</div>
<p>任何传递给 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 的关键字参数—— <em>除了</em> 一个叫 <code class="docutils literal notranslate"><span class="pre">defaults</span></code> 的可选参数——都将在 <a class="reference internal" href="#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a> 调用中使用。如果找到了一个对象，<code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 返回该对象的元组和 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">假设数据库强制执行关键字参数的唯一性（参见 <a class="reference internal" href="fields.html#django.db.models.Field.unique" title="django.db.models.Field.unique"><code class="xref py py-attr docutils literal notranslate"><span class="pre">unique</span></code></a> 或 <a class="reference internal" href="options.html#django.db.models.Options.unique_together" title="django.db.models.Options.unique_together"><code class="xref py py-attr docutils literal notranslate"><span class="pre">unique_together</span></code></a>），这个方法是原子性的。如果关键字参数中使用的字段没有唯一性约束，那么对该方法的并发调用可能会导致插入具有相同参数的多条记录。</p>
</div>
<p>你可以通过将 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">filter()</span></code> 串联起来，并使用 <a class="reference internal" href="#django.db.models.Q" title="django.db.models.Q"><code class="xref py py-class docutils literal notranslate"><span class="pre">Q</span> <span class="pre">对象</span></code></a> 为检索对象指定更复杂的条件。例如，如果 Robert 或 Bob Marley 存在，则检索 Robert 或 Bob Marley，否则创建后者：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>

<span class="n">obj</span><span class="p">,</span> <span class="n">created</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
    <span class="n">Q</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;Bob&#39;</span><span class="p">)</span> <span class="o">|</span> <span class="n">Q</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;Robert&#39;</span><span class="p">),</span>
<span class="p">)</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">last_name</span><span class="o">=</span><span class="s1">&#39;Marley&#39;</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;first_name&#39;</span><span class="p">:</span> <span class="s1">&#39;Bob&#39;</span><span class="p">})</span>
</pre></div>
</div>
<p>如果找到多个对象，<code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 会引发 <a class="reference internal" href="../exceptions.html#django.core.exceptions.MultipleObjectsReturned" title="django.core.exceptions.MultipleObjectsReturned"><code class="xref py py-exc docutils literal notranslate"><span class="pre">MultipleObjectsReturned</span></code></a>。如果没有找到对象，<code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 将实例化并保存一个新对象，返回一个新对象的元组和 <code class="docutils literal notranslate"><span class="pre">True</span></code>。新对象将大致按照以下算法创建：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="s1">&#39;__&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">k</span><span class="p">}</span>
<span class="n">params</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span><span class="p">()</span> <span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">else</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">defaults</span><span class="o">.</span><span class="n">items</span><span class="p">()})</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="p">(</span><span class="o">**</span><span class="n">params</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
<p>在英语中，这意味着从任何不包含双下划线的非 <code class="docutils literal notranslate"><span class="pre">'defaults'</span></code> 关键字参数开始（这将表明一个非精确的查找）。然后添加 <code class="docutils literal notranslate"><span class="pre">defaults</span></code> 的内容，必要时覆盖任何键，并将结果作为模型类的关键字参数。如果 <code class="docutils literal notranslate"><span class="pre">defaults</span></code> 中存在任何可调用对象，则对其进行评估。正如上面所提示的，这是对所使用算法的简化，但它包含了所有相关的细节。内部实现有比这更多的错误检查，并处理一些额外的边缘条件；如果你感兴趣，请阅读代码。</p>
<p>如果你有一个名为 <code class="docutils literal notranslate"><span class="pre">defaults</span></code> 的字段，并且想在 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 中使用它作为精确查询，使用 <code class="docutils literal notranslate"><span class="pre">'defaults__exact'</span></code>，像这样：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Foo</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">defaults__exact</span><span class="o">=</span><span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;defaults&#39;</span><span class="p">:</span> <span class="s1">&#39;baz&#39;</span><span class="p">})</span>
</pre></div>
</div>
<p>当你使用手动指定的主键时，<code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 方法的错误行为与 <a class="reference internal" href="#django.db.models.query.QuerySet.create" title="django.db.models.query.QuerySet.create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">create()</span></code></a> 类似。如果需要创建一个对象，而该键已经存在于数据库中，则会引发一个 <a class="reference internal" href="../exceptions.html#django.db.IntegrityError" title="django.db.IntegrityError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">IntegrityError</span></code></a>。</p>
<p>最后，说一下在 Django 视图中使用 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code> 的问题。请确保只在 <code class="docutils literal notranslate"><span class="pre">POST</span></code> 请求中使用它，除非你有很好的理由不这样做。<code class="docutils literal notranslate"><span class="pre">GET</span></code> 请求不应该对数据有任何影响。相反，当对页面的请求对数据有副作用时，请使用 <code class="docutils literal notranslate"><span class="pre">POST</span></code>。更多内容，请参见在 HTTP 规范中 <span class="target" id="index-6"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc7231.html#section-4.2.1"><strong>安全方法</strong></a>。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p>你可以通过 <a class="reference internal" href="fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyField</span></code></a> 属性和反向关系来使用 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code>。在这种情况下，你将限制在该关系的上下文内进行查询。如果你不持续使用它，这可能会导致一些完整性问题。</p>
<p>如以下模型：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Chapter</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">,</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Book</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">256</span><span class="p">)</span>
    <span class="n">chapters</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ManyToManyField</span><span class="p">(</span><span class="n">Chapter</span><span class="p">)</span>
</pre></div>
</div>
<p>你可以通过 Book 的 chapters 字段使用 <code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code>，但它只能在该书的上下文中获取：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">book</span> <span class="o">=</span> <span class="n">Book</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Ulysses&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">book</span><span class="o">.</span><span class="n">chapters</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Telemachus&quot;</span><span class="p">)</span>
<span class="go">(&lt;Chapter: Telemachus&gt;, True)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">book</span><span class="o">.</span><span class="n">chapters</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Telemachus&quot;</span><span class="p">)</span>
<span class="go">(&lt;Chapter: Telemachus&gt;, False)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Chapter</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Chapter 1&quot;</span><span class="p">)</span>
<span class="go">&lt;Chapter: Chapter 1&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">book</span><span class="o">.</span><span class="n">chapters</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Chapter 1&quot;</span><span class="p">)</span>
<span class="go"># Raises IntegrityError</span>
</pre></div>
</div>
<p class="last">出现这种情况是因为它试图通过“Ulysses”这本书获取或创建“Chapter 1”，但它不能做任何事情：关系不能获取该章，因为它与该书无关，但它也不能创建它，因为 <code class="docutils literal notranslate"><span class="pre">title</span></code> 字段应该是唯一的。</p>
</div>
</div>
<div class="section" id="s-update-or-create">
<span id="update-or-create"></span><h4><code class="docutils literal notranslate"><span class="pre">update_or_create()</span></code><a class="headerlink" href="#update-or-create" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.update_or_create">
<code class="descname">update_or_create</code>(<em>defaults=None</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.update_or_create" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>用给定的 <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> 更新对象的一种方便方法，是必要时创建一个新对象。<code class="docutils literal notranslate"><span class="pre">defaults</span></code> 是用来更新对象的 (field, value) 对的字典。<code class="docutils literal notranslate"><span class="pre">defaults</span></code> 中的值可以是可调用对象。</p>
<p>返回 <code class="docutils literal notranslate"><span class="pre">(object,</span> <span class="pre">created)</span></code> 的元组，其中 <code class="docutils literal notranslate"><span class="pre">object</span></code> 是创建或更新的对象，<code class="docutils literal notranslate"><span class="pre">created</span></code> 是一个布尔值，指定是否创建了一个新对象。</p>
<p><code class="docutils literal notranslate"><span class="pre">update_or_create</span></code> 方法根据给定的 <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> 尝试从数据库中获取一个对象。如果找到了匹配的对象，它就会更新 <code class="docutils literal notranslate"><span class="pre">defaults</span></code> 字典中传递的字段。</p>
<p>这是作为一个快捷方式来处理样板代码。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">defaults</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;first_name&#39;</span><span class="p">:</span> <span class="s1">&#39;Bob&#39;</span><span class="p">}</span>
<span class="k">try</span><span class="p">:</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;John&#39;</span><span class="p">,</span> <span class="n">last_name</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">defaults</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="nb">setattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="k">except</span> <span class="n">Person</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
    <span class="n">new_values</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;first_name&#39;</span><span class="p">:</span> <span class="s1">&#39;John&#39;</span><span class="p">,</span> <span class="s1">&#39;last_name&#39;</span><span class="p">:</span> <span class="s1">&#39;Lennon&#39;</span><span class="p">}</span>
    <span class="n">new_values</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">defaults</span><span class="p">)</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="n">Person</span><span class="p">(</span><span class="o">**</span><span class="n">new_values</span><span class="p">)</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
<p>当模型中的字段数量增加时，这种模式就会变得很笨重。上面的例子可以使用 <code class="docutils literal notranslate"><span class="pre">update_or_create()</span></code> 重写，就像这样：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">obj</span><span class="p">,</span> <span class="n">created</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">update_or_create</span><span class="p">(</span>
    <span class="n">first_name</span><span class="o">=</span><span class="s1">&#39;John&#39;</span><span class="p">,</span> <span class="n">last_name</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">,</span>
    <span class="n">defaults</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;first_name&#39;</span><span class="p">:</span> <span class="s1">&#39;Bob&#39;</span><span class="p">},</span>
<span class="p">)</span>
</pre></div>
</div>
<p>For a detailed description of how names passed in <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> are resolved, see
<a class="reference internal" href="#django.db.models.query.QuerySet.get_or_create" title="django.db.models.query.QuerySet.get_or_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_or_create()</span></code></a>.</p>
<p>如上文 <a class="reference internal" href="#django.db.models.query.QuerySet.get_or_create" title="django.db.models.query.QuerySet.get_or_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_or_create()</span></code></a> 中所述，这种方法容易出现竞争条件，如果不在数据库层面强制执行唯一性，就会导致同时插入多条记录。</p>
<p>就像 <a class="reference internal" href="#django.db.models.query.QuerySet.get_or_create" title="django.db.models.query.QuerySet.get_or_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_or_create()</span></code></a> 和 <a class="reference internal" href="#django.db.models.query.QuerySet.create" title="django.db.models.query.QuerySet.create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">create()</span></code></a> 一样，如果你使用的是手动指定的主键，需要创建一个对象，但该键已经存在于数据库中，就会引发 <a class="reference internal" href="../exceptions.html#django.db.IntegrityError" title="django.db.IntegrityError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">IntegrityError</span></code></a>。</p>
</div>
<div class="section" id="s-bulk-create">
<span id="bulk-create"></span><h4><code class="docutils literal notranslate"><span class="pre">bulk_create()</span></code><a class="headerlink" href="#bulk-create" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.bulk_create">
<code class="descname">bulk_create</code>(<em>objs</em>, <em>batch_size=None</em>, <em>ignore_conflicts=False</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.bulk_create" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>This method inserts the provided list of objects into the database in an
efficient manner (generally only 1 query, no matter how many objects there
are), and returns created objects as a list, in the same order as provided:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">objs</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_create</span><span class="p">([</span>
<span class="gp">... </span>    <span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is a test&#39;</span><span class="p">),</span>
<span class="gp">... </span>    <span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is only a test&#39;</span><span class="p">),</span>
<span class="gp">... </span><span class="p">])</span>
</pre></div>
</div>
<p>不过这有一些注意事项：</p>
<ul>
<li><p class="first">模型的 <code class="docutils literal notranslate"><span class="pre">save()</span></code> 方法将不会被调用，<code class="docutils literal notranslate"><span class="pre">pre_save</span></code> 和 <code class="docutils literal notranslate"><span class="pre">post_save</span></code> 信号将不会被发送。</p>
</li>
<li><p class="first">在多表继承的情况下，它不能与子模型一起工作。</p>
</li>
<li><p class="first">如果模型的主键是一个 <a class="reference internal" href="fields.html#django.db.models.AutoField" title="django.db.models.AutoField"><code class="xref py py-class docutils literal notranslate"><span class="pre">AutoField</span></code></a>，那么主键属性只能在某些数据库（目前是 PostgreSQL 和 MariaDB 10.5+）上被检索到。在其他数据库上，它将不会被设置。</p>
</li>
<li><p class="first">对于多对多的关系，它是行不通的。</p>
</li>
<li><p class="first">它将 <code class="docutils literal notranslate"><span class="pre">objs</span></code> 转换为一个列表，如果 <code class="docutils literal notranslate"><span class="pre">objs</span></code> 是一个生成器，则完全执行 <code class="docutils literal notranslate"><span class="pre">objs</span></code>。这种转换允许检查所有对象，因此任何具有手动设置主键的对象都可以首先插入。如果你想分批插入对象，而不一次性执行整个生成器，你可以使用这种技术，只要对象没有任何手动设置的主键：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">islice</span>

<span class="n">batch_size</span> <span class="o">=</span> <span class="mi">100</span>
<span class="n">objs</span> <span class="o">=</span> <span class="p">(</span><span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;Test </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1000</span><span class="p">))</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
    <span class="n">batch</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">objs</span><span class="p">,</span> <span class="n">batch_size</span><span class="p">))</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">batch</span><span class="p">:</span>
        <span class="k">break</span>
    <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_create</span><span class="p">(</span><span class="n">batch</span><span class="p">,</span> <span class="n">batch_size</span><span class="p">)</span>
</pre></div>
</div>
</li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">batch_size</span></code> 参数控制在一次查询中创建多少对象。默认情况是在一个批次中创建所有对象，但 SQLite 除外，默认情况是每个查询最多使用 999 个变量。</p>
<p>在支持它的数据库上（除了Oracle），将 <code class="docutils literal notranslate"><span class="pre">ignore_conflicts</span></code> 参数设置为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 告诉数据库忽略插入任何不合格的约束条件的行，如重复的唯一值。启用该参数会禁用在每个模型实例上设置主键（如果数据库正常支持的话）。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">在 MySQL 和 MariaDB 上，将 <code class="docutils literal notranslate"><span class="pre">ignore_conflicts</span></code> 参数设置为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 将某些类型的错误，除了重复键之外，变成警告。即使在严格模式下也是如此。例如：无效值或不可空值违规。更多细节请参见 <a class="reference external" href="https://dev.mysql.com/doc/refman/en/sql-mode.html#ignore-strict-comparison">MySQL documentation</a> 和 <a class="reference external" href="https://mariadb.com/kb/en/ignore/">MariaDB documentation</a> 。</p>
</div>
<div class="versionchanged">
<span class="title">Changed in Django 3.1:</span> <p>增加了对 MariaDB 10.5+ 的获取主键属性的支持。</p>
</div>
</div>
<div class="section" id="s-bulk-update">
<span id="bulk-update"></span><h4><code class="docutils literal notranslate"><span class="pre">bulk_update()</span></code><a class="headerlink" href="#bulk-update" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.bulk_update">
<code class="descname">bulk_update</code>(<em>objs</em>, <em>fields</em>, <em>batch_size=None</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.bulk_update" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>该方法可以有效地更新所提供的模型实例上的给定字段，一般只需查询一次：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">objs</span> <span class="o">=</span> <span class="p">[</span>
<span class="gp">... </span>   <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;Entry 1&#39;</span><span class="p">),</span>
<span class="gp">... </span>   <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;Entry 2&#39;</span><span class="p">),</span>
<span class="gp">... </span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">objs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;This is entry 1&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">objs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;This is entry 2&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_update</span><span class="p">(</span><span class="n">objs</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;headline&#39;</span><span class="p">])</span>
</pre></div>
</div>
<p><a class="reference internal" href="#django.db.models.query.QuerySet.update" title="django.db.models.query.QuerySet.update"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.update()</span></code></a> 用于保存更改，所以这比遍历模型列表并对每个模型调用 <code class="docutils literal notranslate"><span class="pre">save()</span></code> 更有效，但它有一些注意事项：</p>
<ul class="simple">
<li>你不能更新模型的主键。</li>
<li>每个模型的 <code class="docutils literal notranslate"><span class="pre">save()</span></code> 方法没有被调用，而且 <a class="reference internal" href="../signals.html#django.db.models.signals.pre_save" title="django.db.models.signals.pre_save"><code class="xref py py-attr docutils literal notranslate"><span class="pre">pre_save</span></code></a> 和 <a class="reference internal" href="../signals.html#django.db.models.signals.post_save" title="django.db.models.signals.post_save"><code class="xref py py-attr docutils literal notranslate"><span class="pre">post_save</span></code></a> 信号没有被发送。</li>
<li>如果更新大量行中的大量列，生成的 SQL 可能非常大。通过指定一个合适的 <code class="docutils literal notranslate"><span class="pre">batch_size</span></code> 来避免这种情况。</li>
<li>更新定义在多表继承祖先上的字段将给每个祖先带来额外的查询。</li>
<li>When an individual batch contains duplicates, only the first instance in that
batch will result in an update.</li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">batch_size</span></code> 参数控制一次查询中保存多少对象。默认值是在一个批次中更新所有对象，但 SQLite 和 Oracle 除外，它们对查询中使用的变量数量有限制。</p>
</div>
<div class="section" id="s-count">
<span id="count"></span><h4><code class="docutils literal notranslate"><span class="pre">count()</span></code><a class="headerlink" href="#count" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.count">
<code class="descname">count</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.count" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个整数，表示数据库中与 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 匹配的对象数量。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Returns the total number of entries in the database.</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>

<span class="c1"># Returns the number of entries whose headline contains &#39;Lennon&#39;</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__contains</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">count()</span></code> 调用在幕后执行 <code class="docutils literal notranslate"><span class="pre">SELECT</span> <span class="pre">COUNT(*)</span></code>，所以你应该总是使用 <code class="docutils literal notranslate"><span class="pre">count()</span></code> 而不是将所有的记录加载到 Python 对象中，然后在结果上调用 <code class="docutils literal notranslate"><span class="pre">len()</span></code> （除非你需要将对象加载到内存中，在这种情况下 <code class="docutils literal notranslate"><span class="pre">len()</span></code> 会更快）。</p>
<p>请注意，如果你想知道 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 中的项数，并且也要从它中检索模型实例（例如，通过迭代它），那么使用 <code class="docutils literal notranslate"><span class="pre">len(queryset)</span></code> 可能更有效，因为它不会像 <code class="docutils literal notranslate"><span class="pre">count()</span></code> 那样引起额外的数据库查询。</p>
<p>If the queryset has already been fully retrieved, <code class="docutils literal notranslate"><span class="pre">count()</span></code> will use that
length rather than perform an extra database query.</p>
</div>
<div class="section" id="s-in-bulk">
<span id="in-bulk"></span><h4><code class="docutils literal notranslate"><span class="pre">in_bulk()</span></code><a class="headerlink" href="#in-bulk" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.in_bulk">
<code class="descname">in_bulk</code>(<em>id_list=None</em>, <em>*</em>, <em>field_name='pk'</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.in_bulk" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>Takes a list of field values (<code class="docutils literal notranslate"><span class="pre">id_list</span></code>) and the <code class="docutils literal notranslate"><span class="pre">field_name</span></code> for those
values, and returns a dictionary mapping each value to an instance of the
object with the given field value. No
<a class="reference internal" href="../exceptions.html#django.core.exceptions.ObjectDoesNotExist" title="django.core.exceptions.ObjectDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">django.core.exceptions.ObjectDoesNotExist</span></code></a> exceptions will ever be raised
by <code class="docutils literal notranslate"><span class="pre">in_bulk</span></code>; that is, any <code class="docutils literal notranslate"><span class="pre">id_list</span></code> value not matching any instance will
simply be ignored. If <code class="docutils literal notranslate"><span class="pre">id_list</span></code> isn't provided, all objects
in the queryset are returned. <code class="docutils literal notranslate"><span class="pre">field_name</span></code> must be a unique field or a
distinct field (if there's only one field specified in <a class="reference internal" href="#django.db.models.query.QuerySet.distinct" title="django.db.models.query.QuerySet.distinct"><code class="xref py py-meth docutils literal notranslate"><span class="pre">distinct()</span></code></a>).
<code class="docutils literal notranslate"><span class="pre">field_name</span></code> defaults to the primary key.</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">in_bulk</span><span class="p">([</span><span class="mi">1</span><span class="p">])</span>
<span class="go">{1: &lt;Blog: Beatles Blog&gt;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">in_bulk</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">])</span>
<span class="go">{1: &lt;Blog: Beatles Blog&gt;, 2: &lt;Blog: Cheddar Talk&gt;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">in_bulk</span><span class="p">([])</span>
<span class="go">{}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">in_bulk</span><span class="p">()</span>
<span class="go">{1: &lt;Blog: Beatles Blog&gt;, 2: &lt;Blog: Cheddar Talk&gt;, 3: &lt;Blog: Django Weblog&gt;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">in_bulk</span><span class="p">([</span><span class="s1">&#39;beatles_blog&#39;</span><span class="p">],</span> <span class="n">field_name</span><span class="o">=</span><span class="s1">&#39;slug&#39;</span><span class="p">)</span>
<span class="go">{&#39;beatles_blog&#39;: &lt;Blog: Beatles Blog&gt;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">distinct</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">in_bulk</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">&#39;name&#39;</span><span class="p">)</span>
<span class="go">{&#39;Beatles Blog&#39;: &lt;Blog: Beatles Blog&gt;, &#39;Cheddar Talk&#39;: &lt;Blog: Cheddar Talk&gt;, &#39;Django Weblog&#39;: &lt;Blog: Django Weblog&gt;}</span>
</pre></div>
</div>
<p>如果你传递 <code class="docutils literal notranslate"><span class="pre">in_bulk()</span></code> 一个空列表，你将得到一个空字典。</p>
<div class="versionchanged">
<span class="title">Changed in Django 3.2:</span> <p>Using a distinct field was allowed.</p>
</div>
</div>
<div class="section" id="s-iterator">
<span id="iterator"></span><h4><code class="docutils literal notranslate"><span class="pre">iterator()</span></code><a class="headerlink" href="#iterator" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.iterator">
<code class="descname">iterator</code>(<em>chunk_size=2000</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.iterator" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>执行 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> （通过执行查询），并在结果上返回一个迭代器（见 <span class="target" id="index-7"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0234"><strong>PEP 234</strong></a>）。<code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 通常会在内部缓存其结果，因此重复执行不会导致额外的查询。相反，<code class="docutils literal notranslate"><span class="pre">iterator()</span></code> 将直接读取结果，而不在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 级别做任何缓存（在内部，默认的迭代器调用 <code class="docutils literal notranslate"><span class="pre">iterator()</span></code> 并缓存返回值）。对于一个只需要访问一次就能返回大量对象的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 来说，这可以带来更好的性能，并显著减少内存。</p>
<p>请注意，在已经被执行的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 上使用 <code class="docutils literal notranslate"><span class="pre">iterator()</span></code> 会迫使它再次执行，重复查询。</p>
<p>另外，使用 <code class="docutils literal notranslate"><span class="pre">iterator()</span></code> 会导致之前的 <code class="docutils literal notranslate"><span class="pre">refetch_related()</span></code> 调用被忽略，因为这两种优化方式放在一起没有意义。</p>
<p>根据数据库后端，查询结果将被一次性加载或使用服务器端的游标从数据库中流转。</p>
<div class="section" id="s-with-server-side-cursors">
<span id="with-server-side-cursors"></span><h5>使用服务器端游标<a class="headerlink" href="#with-server-side-cursors" title="永久链接至标题">¶</a></h5>
<p>Oracle 和 <a class="reference internal" href="../databases.html#postgresql-server-side-cursors"><span class="std std-ref">PostgreSQL</span></a> 使用服务器端的游标从数据库流式传输结果，而不需要将整个结果集加载到内存中。</p>
<p>Oracle 数据库驱动程序总是使用服务器端的游标。</p>
<p>对于服务器端的游标，<code class="docutils literal notranslate"><span class="pre">chunk_size</span></code> 参数指定了要在数据库驱动层缓存的结果数量。获取更大的块数会减少数据库驱动和数据库之间的往返次数，但会牺牲内存。</p>
<p>在 PostgreSQL 上，只有当 <a class="reference internal" href="../settings.html#std:setting-DATABASE-DISABLE_SERVER_SIDE_CURSORS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DISABLE_SERVER_SIDE_CURSORS</span></code></a> 设置为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 时，才会使用服务器端游标。如果你使用的是配置在事务池模式下的连接池器，请阅读 <a class="reference internal" href="../databases.html#transaction-pooling-server-side-cursors"><span class="std std-ref">事务池和服务器端游标</span></a>。当禁用服务器端游标时，其行为与不支持服务器端游标的数据库相同。</p>
</div>
<div class="section" id="s-without-server-side-cursors">
<span id="without-server-side-cursors"></span><h5>没有服务器端游标<a class="headerlink" href="#without-server-side-cursors" title="永久链接至标题">¶</a></h5>
<p>MySQL 不支持流式结果，因此 Python 数据库驱动将整个结果集加载到内存中。然后数据库适配器使用 <span class="target" id="index-8"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0249"><strong>PEP 249</strong></a> 中定义的 <code class="docutils literal notranslate"><span class="pre">fetchmany()</span></code> 方法将结果集转化为 Python 行对象。</p>
<p>SQLite 可以使用 <code class="docutils literal notranslate"><span class="pre">fetchmany()</span></code> 分批获取结果，但由于 SQLite 不提供连接内查询之间的隔离，所以在向被迭代的表写入时要小心。参见 <a class="reference internal" href="../databases.html#sqlite-isolation"><span class="std std-ref">使用 QuerySet.iterator() 时的隔离</span></a> 了解更多信息。</p>
<p><code class="docutils literal notranslate"><span class="pre">chunk_size</span></code> 参数控制 Django 从数据库驱动中获取的批次大小。批量越大，就会减少与数据库驱动通信的开销，但代价是略微增加内存消耗。</p>
<p><code class="docutils literal notranslate"><span class="pre">chunk_size</span></code> 的默认值 2000 来自 <a class="reference external" href="https://www.postgresql.org/message-id/4D2F2C71.8080805%40dndg.it">psycopg 邮件列表的计算</a>。</p>
<blockquote>
<div>假设行数为 10-20 列，文字数据和数字数据混合，2000 要取不到 100KB 的数据，这似乎是一个很好的折中方案，在传输的行数和提前退出循环时丢弃的数据之间。</div></blockquote>
</div>
</div>
<div class="section" id="s-latest">
<span id="latest"></span><h4><code class="docutils literal notranslate"><span class="pre">latest()</span></code><a class="headerlink" href="#latest" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.latest">
<code class="descname">latest</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.latest" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>根据给定的字段，返回表中最新的对象。</p>
<p>这个例子根据 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 字段返回表中最新的 <code class="docutils literal notranslate"><span class="pre">Entry</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">latest</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>你也可以根据几个字段选择最新的。例如，当两个条目具有相同的 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 时，要选择最早的 <code class="docutils literal notranslate"><span class="pre">expire_date</span></code> 条目：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">latest</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">,</span> <span class="s1">&#39;-expire_date&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">'-expire_date'</span></code> 中的负号表示按 <em>降</em> 序排列 <code class="docutils literal notranslate"><span class="pre">expire_date</span></code>。由于 <code class="docutils literal notranslate"><span class="pre">latest()</span></code> 得到的是最后一个结果，所以选择了最早的 <code class="docutils literal notranslate"><span class="pre">expire_date</span></code> 的 <code class="docutils literal notranslate"><span class="pre">Entry</span></code>。</p>
<p>如果你模型的 <a class="reference internal" href="../../topics/db/models.html#meta-options"><span class="std std-ref">Meta</span></a> 指定了 <a class="reference internal" href="options.html#django.db.models.Options.get_latest_by" title="django.db.models.Options.get_latest_by"><code class="xref py py-attr docutils literal notranslate"><span class="pre">get_latest_by</span></code></a>，你可以省略 <code class="docutils literal notranslate"><span class="pre">earliest()</span></code> 或 <code class="docutils literal notranslate"><span class="pre">latest()</span></code> 的任何参数。<a class="reference internal" href="options.html#django.db.models.Options.get_latest_by" title="django.db.models.Options.get_latest_by"><code class="xref py py-attr docutils literal notranslate"><span class="pre">get_latest_by</span></code></a> 中指定的字段将被默认使用。</p>
<p>像 <a class="reference internal" href="#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a>、<code class="docutils literal notranslate"><span class="pre">earliest()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">latest()</span></code>，如果没有给定参数的对象，就会引发 <a class="reference internal" href="class.html#django.db.models.Model.DoesNotExist" title="django.db.models.Model.DoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DoesNotExist</span></code></a>。</p>
<p>请注意，<code class="docutils literal notranslate"><span class="pre">earliest()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">latest()</span></code> 的存在纯粹是为了方便和可读性。</p>
<div class="admonition-earliest-and-latest-may-return-instances-with-null-dates admonition">
<p class="first admonition-title"><code class="docutils literal notranslate"><span class="pre">earliest()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">latest()</span></code> 可能返回日期为空的实例。</p>
<p>由于排序是委托给数据库的，如果使用不同的数据库，允许空值的字段上的结果可能会有不同的排序。例如，PostgreSQL 和 MySQL 将空值排序为高于非空值，而 SQLite 则相反。</p>
<p>你可能想过滤掉空值：</p>
<div class="last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__isnull</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span><span class="o">.</span><span class="n">latest</span><span class="p">(</span><span class="s1">&#39;pub_date&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="s-earliest">
<span id="earliest"></span><h4><code class="docutils literal notranslate"><span class="pre">earliest()</span></code><a class="headerlink" href="#earliest" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.earliest">
<code class="descname">earliest</code>(<em>*fields</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.earliest" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>除了方向改变外，其他工作方式都像 <a class="reference internal" href="#django.db.models.query.QuerySet.last" title="django.db.models.query.QuerySet.last"><code class="xref py py-meth docutils literal notranslate"><span class="pre">last()</span></code></a>。</p>
</div>
<div class="section" id="s-first">
<span id="first"></span><h4><code class="docutils literal notranslate"><span class="pre">first()</span></code><a class="headerlink" href="#first" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.first">
<code class="descname">first</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.first" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回查询集匹配的第一个对象，如果没有匹配的对象，则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。如果 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 没有定义排序，那么查询集自动按主键排序。这可能会影响聚合结果，如 <a class="reference internal" href="../../topics/db/aggregation.html#aggregation-ordering-interaction"><span class="std std-ref">Interaction with order_by()</span></a> 中所述。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">p</span> <span class="o">=</span> <span class="n">Article</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;title&#39;</span><span class="p">,</span> <span class="s1">&#39;pub_date&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
</pre></div>
</div>
<p>请注意，<code class="docutils literal notranslate"><span class="pre">first()</span></code> 是一个方便的方法，下面的代码示例相当于上面的例子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="n">p</span> <span class="o">=</span> <span class="n">Article</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;title&#39;</span><span class="p">,</span> <span class="s1">&#39;pub_date&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
    <span class="n">p</span> <span class="o">=</span> <span class="kc">None</span>
</pre></div>
</div>
</div>
<div class="section" id="s-last">
<span id="last"></span><h4><code class="docutils literal notranslate"><span class="pre">last()</span></code><a class="headerlink" href="#last" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.last">
<code class="descname">last</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.last" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>与 <a class="reference internal" href="#django.db.models.query.QuerySet.first" title="django.db.models.query.QuerySet.first"><code class="xref py py-meth docutils literal notranslate"><span class="pre">first()</span></code></a> 工作原理相同，但返回的是查询集中的最后一个对象。</p>
</div>
<div class="section" id="s-aggregate">
<span id="aggregate"></span><h4><code class="docutils literal notranslate"><span class="pre">aggregate()</span></code><a class="headerlink" href="#aggregate" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.aggregate">
<code class="descname">aggregate</code>(<em>*args</em>, <em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.aggregate" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回对 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 计算的聚合值（平均值、总和等）的字典。<code class="docutils literal notranslate"><span class="pre">aggregate()</span></code> 的每个参数都指定了一个将被包含在返回的字典中的值。</p>
<p>Django 提供的聚合函数在下面的 <a class="reference internal" href="#id5">Aggregation Functions</a> 中介绍。由于聚合函数也是 <a class="reference internal" href="expressions.html"><span class="doc">查询表达式</span></a>，所以你可以将聚合函数与其他聚合函数或值结合起来，创建复杂的聚合函数。</p>
<p>使用关键字参数指定的聚合将使用关键字作为注解的名称。匿名参数将根据聚合函数的名称和被聚合的模型字段为其生成一个名称。复杂的聚合不能使用匿名参数，必须指定一个关键字参数作为别名。</p>
<p>例如，当你在处理博客条目时，你可能想知道贡献过博客条目的作者数量：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">{&#39;entry__count&#39;: 16}</span>
</pre></div>
</div>
<p>通过使用关键字参数来指定聚合函数，可以控制返回的聚合值的名称：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">q</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">number_of_entries</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">&#39;entry&#39;</span><span class="p">))</span>
<span class="go">{&#39;number_of_entries&#39;: 16}</span>
</pre></div>
</div>
<p>关于聚合的深入讨论，见 <a class="reference internal" href="../../topics/db/aggregation.html"><span class="doc">关于聚合的专题指南</span></a>。</p>
</div>
<div class="section" id="s-exists">
<span id="exists"></span><h4><code class="docutils literal notranslate"><span class="pre">exists()</span></code><a class="headerlink" href="#exists" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.exists">
<code class="descname">exists</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.exists" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 包含任何结果，则返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>，如果不包含，则返回 <code class="docutils literal notranslate"><span class="pre">False</span></code>。该函数试图以最简单、最快速的方式执行查询，但它 <em>执行</em> 的查询与普通的 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 查询几乎相同。</p>
<p><code class="xref py py-meth docutils literal notranslate"><span class="pre">exences()</span></code> 对于搜索与 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 中的对象成员资格和 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 中的任何对象的存在有关的搜索是有用的，特别是在大型 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 的情况下。</p>
<p>查找具有唯一字段（如 <code class="docutils literal notranslate"><span class="pre">primary_key</span></code>）的模型是否为 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 成员的最有效方法是：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">123</span><span class="p">)</span>
<span class="k">if</span> <span class="n">some_queryset</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">entry</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Entry contained in queryset&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>这种方法比下面需要执行和迭代整个查询集的方法更快：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">some_queryset</span><span class="p">:</span>
   <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Entry contained in QuerySet&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>并查找一个查询集是否包含任何项目：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">some_queryset</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;There is at least one object in some_queryset&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>这种方法比下面的方法更快：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">some_queryset</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;There is at least one object in some_queryset&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>...但程度不高（因此需要大量的查询集才能获得效率提升）。</p>
<p>此外，如果一个 <code class="docutils literal notranslate"><span class="pre">some_queryset</span></code> 还没有被执行，但你知道它会在某个时候被执行，那么使用 <code class="docutils literal notranslate"><span class="pre">some_queryset.exences()</span></code> 比使用 <code class="docutils literal notranslate"><span class="pre">bool(some_queryset)</span></code> 会做更多的总体工作（一个存在性检查的查询加上一个额外的查询，以便以后检索结果），后者检索结果，然后检查是否有任何返回。</p>
</div>
<div class="section" id="s-update">
<span id="update"></span><h4><code class="docutils literal notranslate"><span class="pre">update()</span></code><a class="headerlink" href="#update" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.update">
<code class="descname">update</code>(<em>**kwargs</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.update" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>对指定的字段执行 SQL 更新查询，并返回匹配的行数（如果有些行已经有了新的值，则可能不等于更新的行数）。</p>
<p>例如，要关闭 2010 年发表的所有博客条目的评论，你可以这样做：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="mi">2010</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</pre></div>
</div>
<p>（假定你的 <code class="docutils literal notranslate"><span class="pre">Entry</span></code> 模型有 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 和 <code class="docutils literal notranslate"><span class="pre">comments_on</span></code>。）</p>
<p>你可以更新多个字段——没有数量限制。例如，这里我们更新了 <code class="docutils literal notranslate"><span class="pre">comments_on</span></code> 和 <code class="docutils literal notranslate"><span class="pre">headline</span></code> 字段：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="mi">2010</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is old&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">update()</span></code> 方法是即时应用的，对被更新的 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 唯一的限制是只能更新模型主表中的列，不能更新相关模型。你不能这样做，比如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">blog__name</span><span class="o">=</span><span class="s1">&#39;foo&#39;</span><span class="p">)</span> <span class="c1"># Won&#39;t work!</span>
</pre></div>
</div>
<p>但仍可根据相关字段进行过滤：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">blog__id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>你不能在一个 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 上调用 <code class="docutils literal notranslate"><span class="pre">update()</span></code>，因为它已经被取走了一个片断或者不能再被过滤。</p>
<p><code class="docutils literal notranslate"><span class="pre">update()</span></code> 方法返回受影响的行数：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">64</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">1</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">slug</span><span class="o">=</span><span class="s1">&#39;nonexistent-slug&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">0</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="mi">2010</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="go">132</span>
</pre></div>
</div>
<p>如果你只是更新一条记录，不需要对模型对象做任何事情，最有效的方法是调用 <code class="docutils literal notranslate"><span class="pre">update()</span></code>，而不是将模型对象加载到内存中。例如，不要这样做：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">e</span><span class="o">.</span><span class="n">comments_on</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">e</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
<p>...要这样做：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">comments_on</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</pre></div>
</div>
<p>使用 <code class="docutils literal notranslate"><span class="pre">update()</span></code> 还可以防止在加载对象和调用 <code class="docutils literal notranslate"><span class="pre">save()</span></code> 之间的短暂时间内数据库中的某些东西可能发生变化的竞争条件。</p>
<p>最后，要知道，<code class="docutils literal notranslate"><span class="pre">update()</span></code> 是在 SQL 级别上进行更新，因此，它不会在模型上调用任何 <code class="docutils literal notranslate"><span class="pre">save()</span></code> 方法，也不会发出 <code class="xref py py-attr docutils literal notranslate"><span class="pre">pre_save</span></code> 或 <a class="reference internal" href="../signals.html#django.db.models.signals.post_save" title="django.db.models.signals.post_save"><code class="xref py py-attr docutils literal notranslate"><span class="pre">post_save</span></code></a> 信号（这是调用 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Model.save()</span></code></a> 的结果）。如果你想为一个有自定义 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code></a> 方法的模型更新一堆记录，在它们上面循环并调用 <a class="reference internal" href="instances.html#django.db.models.Model.save" title="django.db.models.Model.save"><code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code></a>，像这样：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="mi">2010</span><span class="p">):</span>
    <span class="n">e</span><span class="o">.</span><span class="n">comments_on</span> <span class="o">=</span> <span class="kc">False</span>
    <span class="n">e</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
<div class="section" id="s-ordered-queryset">
<span id="ordered-queryset"></span><h5>Ordered queryset<a class="headerlink" href="#ordered-queryset" title="永久链接至标题">¶</a></h5>
<div class="versionadded">
<span class="title">New in Django 3.2.</span> </div>
<p>Chaining <code class="docutils literal notranslate"><span class="pre">order_by()</span></code> with <code class="docutils literal notranslate"><span class="pre">update()</span></code> is supported only on MariaDB and
MySQL, and is ignored for different databases. This is useful for updating a
unique field in the order that is specified without conflicts. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">&#39;-number&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">number</span><span class="o">=</span><span class="n">F</span><span class="p">(</span><span class="s1">&#39;number&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last"><code class="docutils literal notranslate"><span class="pre">order_by()</span></code> clause will be ignored if it contains annotations, inherited
fields, or lookups spanning relations.</p>
</div>
</div>
</div>
<div class="section" id="s-delete">
<span id="delete"></span><h4><code class="docutils literal notranslate"><span class="pre">delete()</span></code><a class="headerlink" href="#delete" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.delete">
<code class="descname">delete</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.delete" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>对 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 中的所有行执行 SQL 删除查询，并返回删除的对象数量和每个对象类型的删除数量的字典。</p>
<p><code class="docutils literal notranslate"><span class="pre">delete()</span></code> 是即时应用的。你不能对已经被取走一个片断或不能再被过滤的 <a class="reference internal" href="#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><code class="xref py py-class docutils literal notranslate"><span class="pre">QuerySet</span></code></a> 调用 <code class="docutils literal notranslate"><span class="pre">delete()</span></code>。</p>
<p>例如，要删除某个博客中的所有条目：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">b</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>

<span class="go"># Delete all the entries belonging to this Blog.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">blog</span><span class="o">=</span><span class="n">b</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="go">(4, {&#39;weblog.Entry&#39;: 2, &#39;weblog.Entry_authors&#39;: 2})</span>
</pre></div>
</div>
<p>默认情况下，Django 的 <a class="reference internal" href="fields.html#django.db.models.ForeignKey" title="django.db.models.ForeignKey"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForeignKey</span></code></a> 模拟了 SQL 约束 <code class="docutils literal notranslate"><span class="pre">ON</span> <span class="pre">DELETE</span> <span class="pre">CASCADE</span></code>——换句话说，任何外键指向要删除的对象的对象都会被一起删除。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">blogs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>

<span class="go"># This will delete all Blogs and all of their Entry objects.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">blogs</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="go">(5, {&#39;weblog.Blog&#39;: 1, &#39;weblog.Entry&#39;: 2, &#39;weblog.Entry_authors&#39;: 2})</span>
</pre></div>
</div>
<p>这种级联行为通过 <a class="reference internal" href="fields.html#django.db.models.ForeignKey" title="django.db.models.ForeignKey"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForeignKey</span></code></a> 的 <a class="reference internal" href="fields.html#django.db.models.ForeignKey.on_delete" title="django.db.models.ForeignKey.on_delete"><code class="xref py py-attr docutils literal notranslate"><span class="pre">on_delete</span></code></a> 参数定义。</p>
<p><code class="docutils literal notranslate"><span class="pre">delete()</span></code> 方法进行批量删除，并不调用模型上的任何 <code class="docutils literal notranslate"><span class="pre">delete()</span></code> 方法。但是，它确实为所有被删除的对象（包括级联删除）发出 <a class="reference internal" href="../signals.html#django.db.models.signals.pre_delete" title="django.db.models.signals.pre_delete"><code class="xref py py-data docutils literal notranslate"><span class="pre">pre_delete</span></code></a> 和 <a class="reference internal" href="../signals.html#django.db.models.signals.post_delete" title="django.db.models.signals.post_delete"><code class="xref py py-data docutils literal notranslate"><span class="pre">post_delete</span></code></a> 信号。</p>
<p>Django 需要将对象获取到内存中来发送信号和处理级联。但是，如果没有级联和信号，那么 Django 可能会采取快速路径删除对象，而不需要将其获取到内存中。对于大面积的删除，这可以使内存使用量大大降低。也可以减少执行查询的数量。</p>
<p>设置为 <a class="reference internal" href="fields.html#django.db.models.ForeignKey.on_delete" title="django.db.models.ForeignKey.on_delete"><code class="xref py py-attr docutils literal notranslate"><span class="pre">on_delete</span></code></a> <code class="docutils literal notranslate"><span class="pre">DO_NOTHING</span></code> 的外键不会阻止在删除时采取快速路径。</p>
<p>需要注意的是，对象删除中产生的查询是一个实现细节，可能会发生变化。</p>
</div>
<div class="section" id="s-as-manager">
<span id="as-manager"></span><h4><code class="docutils literal notranslate"><span class="pre">as_manager()</span></code><a class="headerlink" href="#as-manager" title="永久链接至标题">¶</a></h4>
<dl class="classmethod">
<dt id="django.db.models.query.QuerySet.as_manager">
<em class="property">classmethod </em><code class="descname">as_manager</code>()<a class="headerlink" href="#django.db.models.query.QuerySet.as_manager" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>类方法，该方法返回一个 <a class="reference internal" href="../../topics/db/managers.html#django.db.models.Manager" title="django.db.models.Manager"><code class="xref py py-class docutils literal notranslate"><span class="pre">Manager</span></code></a> 的实例，其中包含 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的方法的副本。详见 <a class="reference internal" href="../../topics/db/managers.html#create-manager-with-queryset-methods"><span class="std std-ref">创建带有 QuerySet 方法的管理器</span></a> 。</p>
</div>
<div class="section" id="s-explain">
<span id="explain"></span><h4><code class="docutils literal notranslate"><span class="pre">explain()</span></code><a class="headerlink" href="#explain" title="永久链接至标题">¶</a></h4>
<dl class="method">
<dt id="django.db.models.query.QuerySet.explain">
<code class="descname">explain</code>(<em>format=None</em>, <em>**options</em>)<a class="headerlink" href="#django.db.models.query.QuerySet.explain" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>返回一个 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的执行计划的字符串，它详细说明了数据库将如何执行查询，包括将使用的任何索引或联接。了解这些细节可以帮助你提高慢速查询的性能。</p>
<p>例如，当使用 PostgreSQL：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s1">&#39;My Blog&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">explain</span><span class="p">())</span>
<span class="go">Seq Scan on blog  (cost=0.00..35.50 rows=10 width=12)</span>
<span class="go">  Filter: (title = &#39;My Blog&#39;::bpchar)</span>
</pre></div>
</div>
<p>不同数据库之间的输出有很大的不同。</p>
<p><code class="docutils literal notranslate"><span class="pre">explain()</span></code> 得到了所有内置数据库后端的支持，但 Oracle 除外，因为在那里的实现并不直接。</p>
<p><code class="docutils literal notranslate"><span class="pre">format</span></code> 参数改变数据库默认的输出格式，通常是基于文本的。PostgreSQL 支持 <code class="docutils literal notranslate"><span class="pre">''TEXT'</span></code>、<code class="docutils literal notranslate"><span class="pre">'JSON'</span></code>、<code class="docutils literal notranslate"><span class="pre">'YAML'</span></code> 和 <code class="docutils literal notranslate"><span class="pre">'XML'</span></code> 格式。MariaDB 和 MySQL 支持 <code class="docutils literal notranslate"><span class="pre">''TEXT'</span></code> （也叫 <code class="docutils literal notranslate"><span class="pre">'TRADITIONAL'</span></code>）和 <code class="docutils literal notranslate"><span class="pre">'JSON'</span></code> 格式。MySQL 8.0.16+ 还支持改进的 <code class="docutils literal notranslate"><span class="pre">'TREE'</span></code> 格式，它类似于 PostgreSQL 的 <code class="docutils literal notranslate"><span class="pre">'TEXT'</span></code> 输出，如果支持的话，默认使用。</p>
<p>一些数据库接受可以返回更多查询信息的标志。将这些标志作为关键字参数传递。例如，当使用 PostgreSQL：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s1">&#39;My Blog&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">explain</span><span class="p">(</span><span class="n">verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">analyze</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
<span class="go">Seq Scan on public.blog  (cost=0.00..35.50 rows=10 width=12) (actual time=0.004..0.004 rows=10 loops=1)</span>
<span class="go">  Output: id, title</span>
<span class="go">  Filter: (blog.title = &#39;My Blog&#39;::bpchar)</span>
<span class="go">Planning time: 0.064 ms</span>
<span class="go">Execution time: 0.058 ms</span>
</pre></div>
</div>
<p>有些数据库接受的标志可以返回更多 在一些数据库上，标志可能会导致查询被执行，这可能会对你的数据库产生不利影响。 例如，MariaDB、MySQL 8.0.18+ 和 PostgreSQL 支持的 <code class="docutils literal notranslate"><span class="pre">ANALYZE</span></code> 标志，如果有触发器或调用函数，即使是 <code class="docutils literal notranslate"><span class="pre">SELECT</span></code> 查询，也可能导致数据的改变。</p>
<div class="versionchanged">
<span class="title">Changed in Django 3.1:</span> <p>在 MySQL 8.0.16+ 上增加了对 <code class="docutils literal notranslate"><span class="pre">'TREE'</span></code> 格式的支持，在 MariaDB 和 MySQL 8.0.18+ 上增加了 <code class="docutils literal notranslate"><span class="pre">analyze</span></code> 选项。</p>
</div>
</div>
</div>
<div class="section" id="s-field-lookups">
<span id="s-id4"></span><span id="field-lookups"></span><span id="id4"></span><h3><code class="docutils literal notranslate"><span class="pre">Field</span></code> 查找<a class="headerlink" href="#field-lookups" title="永久链接至标题">¶</a></h3>
<p>字段查找是指定 SQL <code class="docutils literal notranslate"><span class="pre">WHERE</span></code> 子句的方法。它们被指定为 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 方法 <a class="reference internal" href="#django.db.models.query.QuerySet.filter" title="django.db.models.query.QuerySet.filter"><code class="xref py py-meth docutils literal notranslate"><span class="pre">filter()</span></code></a>、<a class="reference internal" href="#django.db.models.query.QuerySet.exclude" title="django.db.models.query.QuerySet.exclude"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exclude()</span></code></a> 和 <a class="reference internal" href="#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a> 的关键字参数。</p>
<p>介绍见 <a class="reference internal" href="../../topics/db/queries.html#field-lookups-intro"><span class="std std-ref">模型和数据库查询文档</span></a>。</p>
<p>Django 的内置查找功能如下。也可以为模型字段写 <a class="reference internal" href="../../howto/custom-lookups.html"><span class="doc">自定义查找</span></a>。</p>
<p>为方便起见，当没有提供查找类型时（如 <code class="docutils literal notranslate"><span class="pre">Entry.objects.get(id=14)</span></code>），查找类型被假定为 <a class="reference internal" href="#std:fieldlookup-exact"><code class="xref std std-lookup docutils literal notranslate"><span class="pre">exact</span></code></a>。</p>
<div class="section" id="s-exact">
<span id="s-std:fieldlookup-exact"></span><span id="exact"></span><span id="std:fieldlookup-exact"></span><h4><code class="docutils literal notranslate"><span class="pre">exact</span></code><a class="headerlink" href="#exact" title="永久链接至标题">¶</a></h4>
<p>完全匹配。如果提供的比较值是 <code class="docutils literal notranslate"><span class="pre">None</span></code>，它将被解释为 SQL <code class="docutils literal notranslate"><span class="pre">NULL</span></code> （详见 <a class="reference internal" href="#std:fieldlookup-isnull"><code class="xref std std-lookup docutils literal notranslate"><span class="pre">isnull</span></code></a>）。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">id__exact</span><span class="o">=</span><span class="mi">14</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">id__exact</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">14</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">id</span> <span class="k">IS</span> <span class="k">NULL</span><span class="p">;</span>
</pre></div>
</div>
<div class="admonition-mysql-comparisons admonition">
<p class="first admonition-title">MySQL 比较</p>
<p class="last">在 MySQL 中，数据库表的“字符序”设置决定了 <code class="docutils literal notranslate"><span class="pre">act</span></code> 比较是否区分大小写。这是一个数据库设置，而 <em>不是</em> Django 设置。可以配置你的 MySQL 表来使用区分大小写的比较，但是会有一些折衷。关于这方面的更多信息，请参阅 <a class="reference internal" href="../databases.html"><span class="doc">数据库</span></a> 文档中的 <a class="reference internal" href="../databases.html#mysql-collation"><span class="std std-ref">字符序部分</span></a>。</p>
</div>
</div>
<div class="section" id="s-iexact">
<span id="s-std:fieldlookup-iexact"></span><span id="iexact"></span><span id="std:fieldlookup-iexact"></span><h4><code class="docutils literal notranslate"><span class="pre">iexact</span></code><a class="headerlink" href="#iexact" title="永久链接至标题">¶</a></h4>
<p>不区分大小写的完全匹配。如果提供的比较值是 <code class="docutils literal notranslate"><span class="pre">None</span></code>，它将被解释为 SQL <code class="docutils literal notranslate"><span class="pre">NULL</span></code> （详见 <a class="reference internal" href="#std:fieldlookup-isnull"><code class="xref std std-lookup docutils literal notranslate"><span class="pre">isnull</span></code></a>）。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name__iexact</span><span class="o">=</span><span class="s1">&#39;beatles blog&#39;</span><span class="p">)</span>
<span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name__iexact</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">name</span> <span class="k">ILIKE</span> <span class="s1">&#39;beatles blog&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">name</span> <span class="k">IS</span> <span class="k">NULL</span><span class="p">;</span>
</pre></div>
</div>
<p>注意第一个查询会匹配 <code class="docutils literal notranslate"><span class="pre">'Beatles</span> <span class="pre">Blog'</span></code>、<code class="docutils literal notranslate"><span class="pre">'beatles</span> <span class="pre">blog'</span></code>、<code class="docutils literal notranslate"><span class="pre">'BeAtLes</span> <span class="pre">BLoG'</span></code> 等。</p>
<div class="admonition-sqlite-users admonition">
<p class="first admonition-title">SQLite 用户</p>
<p class="last">当使用 SQLite 后台和非 ASCII 字符串时，请记住 <a class="reference internal" href="../databases.html#sqlite-string-matching"><span class="std std-ref">database note</span></a> 中关于字符串比较的内容。SQLite 对非 ASCII 字符串不进行区分大小写的匹配。</p>
</div>
</div>
<div class="section" id="s-contains">
<span id="s-std:fieldlookup-contains"></span><span id="contains"></span><span id="std:fieldlookup-contains"></span><h4><code class="docutils literal notranslate"><span class="pre">contains</span></code><a class="headerlink" href="#contains" title="永久链接至标题">¶</a></h4>
<p>区分大小写的包含测试。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">headline__contains</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">LIKE</span> <span class="s1">&#39;%Lennon%&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>请注意，这将与标题 <code class="docutils literal notranslate"><span class="pre">'Lennon</span> <span class="pre">honored</span> <span class="pre">today'</span></code> 相匹配，而不是 <code class="docutils literal notranslate"><span class="pre">'lennon</span> <span class="pre">honored</span> <span class="pre">today'</span></code>。</p>
<div class="admonition-sqlite-users admonition">
<p class="first admonition-title">SQLite 用户</p>
<p class="last">SQLite 不支持区分大小写的 <code class="docutils literal notranslate"><span class="pre">LIKE</span></code> 语句；<code class="docutils literal notranslate"><span class="pre">contains</span></code> 的作用就像 SQLite 的 <code class="docutils literal notranslate"><span class="pre">icontains</span></code>。更多信息请参见 <a class="reference internal" href="../databases.html#sqlite-string-matching"><span class="std std-ref">database note</span></a>。</p>
</div>
</div>
<div class="section" id="s-icontains">
<span id="s-std:fieldlookup-icontains"></span><span id="icontains"></span><span id="std:fieldlookup-icontains"></span><h4><code class="docutils literal notranslate"><span class="pre">icontains</span></code><a class="headerlink" href="#icontains" title="永久链接至标题">¶</a></h4>
<p>不区分大小写的包含测试。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">headline__icontains</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">ILIKE</span> <span class="s1">&#39;%Lennon%&#39;</span><span class="p">;</span>
</pre></div>
</div>
<div class="admonition-sqlite-users admonition">
<p class="first admonition-title">SQLite 用户</p>
<p class="last">当使用 SQLite 后端和非 ASCII 字符串时，请记住 <a class="reference internal" href="../databases.html#sqlite-string-matching"><span class="std std-ref">database note</span></a> 中关于字符串比较的内容。</p>
</div>
</div>
<div class="section" id="s-in">
<span id="s-std:fieldlookup-in"></span><span id="in"></span><span id="std:fieldlookup-in"></span><h4><code class="docutils literal notranslate"><span class="pre">in</span></code><a class="headerlink" href="#in" title="永久链接至标题">¶</a></h4>
<p>在一个给定的可迭代对象中；通常是一个列表、元组或查询集。这不是一个常见的用例，但字符串（可迭代）是可以接受的。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">id__in</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">])</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__in</span><span class="o">=</span><span class="s1">&#39;abc&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">id</span> <span class="k">IN</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">IN</span> <span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span> <span class="s1">&#39;c&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>你也可以使用一个查询集来动态计算值列表，而不是提供一个字面值列表：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">inner_qs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__contains</span><span class="o">=</span><span class="s1">&#39;Cheddar&#39;</span><span class="p">)</span>
<span class="n">entries</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">blog__in</span><span class="o">=</span><span class="n">inner_qs</span><span class="p">)</span>
</pre></div>
</div>
<p>该查询集将作为子选择语句执行：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">blog</span><span class="p">.</span><span class="n">id</span> <span class="k">IN</span> <span class="p">(</span><span class="k">SELECT</span> <span class="n">id</span> <span class="k">FROM</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">NAME</span> <span class="k">LIKE</span> <span class="s1">&#39;%Cheddar%&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>如果你把一个由 <code class="docutils literal notranslate"><span class="pre">values()</span></code> 或 <code class="docutils literal notranslate"><span class="pre">values_list()</span></code> 产生的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 作为值传递给 <code class="docutils literal notranslate"><span class="pre">__in</span></code> 查找，你需要确保你只提取结果中的一个字段。例如，这样做就可以了（过滤博客名）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">inner_qs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__contains</span><span class="o">=</span><span class="s1">&#39;Ch&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span>
<span class="n">entries</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">blog__name__in</span><span class="o">=</span><span class="n">inner_qs</span><span class="p">)</span>
</pre></div>
</div>
<p>这个例子会引发一个异常，因为内部查询正试图提取两个字段值，而预期只有一个：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Bad code! Will raise a TypeError.</span>
<span class="n">inner_qs</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__contains</span><span class="o">=</span><span class="s1">&#39;Ch&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">values</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="n">entries</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">blog__name__in</span><span class="o">=</span><span class="n">inner_qs</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition-performance-considerations admonition" id="nested-queries-performance">
<p class="first admonition-title">性能考量</p>
<p>谨慎使用嵌套查询，了解你的数据库服务器的性能特点（如果有疑问，请做基准测试！）。一些数据库后端，最主要的是 MySQL，并不能很好地优化嵌套查询。在这些情况下，提取一个值的列表，然后将其传递到第二个查询中会更有效率。也就是说，执行两个查询而不是一个查询：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">values</span> <span class="o">=</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
        <span class="n">name__contains</span><span class="o">=</span><span class="s1">&#39;Cheddar&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">&#39;pk&#39;</span><span class="p">,</span> <span class="n">flat</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">entries</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">blog__in</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">values</span><span class="p">))</span>
</pre></div>
</div>
<p class="last">注意 Blog <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 周围的 <code class="docutils literal notranslate"><span class="pre">list()</span></code> 调用，以强制执行第一个查询。如果没有它，一个嵌套查询就会被执行，因为 <a class="reference internal" href="../../topics/db/queries.html#querysets-are-lazy"><span class="std std-ref">QuerySet 是惰性的</span></a>。</p>
</div>
</div>
<div class="section" id="s-gt">
<span id="s-std:fieldlookup-gt"></span><span id="gt"></span><span id="std:fieldlookup-gt"></span><h4><code class="docutils literal notranslate"><span class="pre">gt</span></code><a class="headerlink" href="#gt" title="永久链接至标题">¶</a></h4>
<p>大于。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">id__gt</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">id</span> <span class="o">&gt;</span> <span class="mi">4</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="s-gte">
<span id="s-std:fieldlookup-gte"></span><span id="gte"></span><span id="std:fieldlookup-gte"></span><h4><code class="docutils literal notranslate"><span class="pre">gte</span></code><a class="headerlink" href="#gte" title="永久链接至标题">¶</a></h4>
<p>大于等于。</p>
</div>
<div class="section" id="s-lt">
<span id="s-std:fieldlookup-lt"></span><span id="lt"></span><span id="std:fieldlookup-lt"></span><h4><code class="docutils literal notranslate"><span class="pre">lt</span></code><a class="headerlink" href="#lt" title="永久链接至标题">¶</a></h4>
<p>小于。</p>
</div>
<div class="section" id="s-lte">
<span id="s-std:fieldlookup-lte"></span><span id="lte"></span><span id="std:fieldlookup-lte"></span><h4><code class="docutils literal notranslate"><span class="pre">lte</span></code><a class="headerlink" href="#lte" title="永久链接至标题">¶</a></h4>
<p>小于等于</p>
</div>
<div class="section" id="s-startswith">
<span id="s-std:fieldlookup-startswith"></span><span id="startswith"></span><span id="std:fieldlookup-startswith"></span><h4><code class="docutils literal notranslate"><span class="pre">startswith</span></code><a class="headerlink" href="#startswith" title="永久链接至标题">¶</a></h4>
<p>区分大小写的开头为。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__startswith</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">LIKE</span> <span class="s1">&#39;Lennon%&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>SQLite 不支持区分大小写的 <code class="docutils literal notranslate"><span class="pre">LIKE</span></code> 语句；<code class="docutils literal notranslate"><span class="pre">startswith</span></code> 的作用就像 SQLite 的 <code class="docutils literal notranslate"><span class="pre">istartswith</span></code>。</p>
</div>
<div class="section" id="s-istartswith">
<span id="s-std:fieldlookup-istartswith"></span><span id="istartswith"></span><span id="std:fieldlookup-istartswith"></span><h4><code class="docutils literal notranslate"><span class="pre">istartswith</span></code><a class="headerlink" href="#istartswith" title="永久链接至标题">¶</a></h4>
<p>不区分大小写的开头为。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__istartswith</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">ILIKE</span> <span class="s1">&#39;Lennon%&#39;</span><span class="p">;</span>
</pre></div>
</div>
<div class="admonition-sqlite-users admonition">
<p class="first admonition-title">SQLite 用户</p>
<p class="last">当使用 SQLite 后端和非 ASCII 字符串时，请记住 <a class="reference internal" href="../databases.html#sqlite-string-matching"><span class="std std-ref">database note</span></a> 中关于字符串比较的内容。</p>
</div>
</div>
<div class="section" id="s-endswith">
<span id="s-std:fieldlookup-endswith"></span><span id="endswith"></span><span id="std:fieldlookup-endswith"></span><h4><code class="docutils literal notranslate"><span class="pre">endswith</span></code><a class="headerlink" href="#endswith" title="永久链接至标题">¶</a></h4>
<p>区分大小写的结尾为。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__endswith</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">LIKE</span> <span class="s1">&#39;%Lennon&#39;</span><span class="p">;</span>
</pre></div>
</div>
<div class="admonition-sqlite-users admonition">
<p class="first admonition-title">SQLite 用户</p>
<p class="last">SQLite 不支持区分大小写的 <code class="docutils literal notranslate"><span class="pre">LIKE</span></code> 语句；<code class="docutils literal notranslate"><span class="pre">endswith</span></code> 的作用类似于 SQLite 的 <code class="docutils literal notranslate"><span class="pre">iendswith</span></code>。更多内容请参考 <a class="reference internal" href="../databases.html#sqlite-string-matching"><span class="std std-ref">database note</span></a> 文档。</p>
</div>
</div>
<div class="section" id="s-iendswith">
<span id="s-std:fieldlookup-iendswith"></span><span id="iendswith"></span><span id="std:fieldlookup-iendswith"></span><h4><code class="docutils literal notranslate"><span class="pre">iendswith</span></code><a class="headerlink" href="#iendswith" title="永久链接至标题">¶</a></h4>
<p>不区分大小写的结尾为。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">headline__iendswith</span><span class="o">=</span><span class="s1">&#39;Lennon&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">headline</span> <span class="k">ILIKE</span> <span class="s1">&#39;%Lennon&#39;</span>
</pre></div>
</div>
<div class="admonition-sqlite-users admonition">
<p class="first admonition-title">SQLite 用户</p>
<p class="last">当使用 SQLite 后端和非 ASCII 字符串时，请记住 <a class="reference internal" href="../databases.html#sqlite-string-matching"><span class="std std-ref">database note</span></a> 中关于字符串比较的内容。</p>
</div>
</div>
<div class="section" id="s-range">
<span id="s-std:fieldlookup-range"></span><span id="range"></span><span id="std:fieldlookup-range"></span><h4><code class="docutils literal notranslate"><span class="pre">range</span></code><a class="headerlink" href="#range" title="永久链接至标题">¶</a></h4>
<p>范围测试（含）。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">datetime</span>
<span class="n">start_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">end_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">31</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__range</span><span class="o">=</span><span class="p">(</span><span class="n">start_date</span><span class="p">,</span> <span class="n">end_date</span><span class="p">))</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">pub_date</span> <span class="k">BETWEEN</span> <span class="s1">&#39;2005-01-01&#39;</span> <span class="k">and</span> <span class="s1">&#39;2005-03-31&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>在 SQL 中，你可以在任何你可以使用 <code class="docutils literal notranslate"><span class="pre">BETWEEN</span></code> 的地方使用 <code class="docutils literal notranslate"><span class="pre">range</span></code>——用于日期、数字甚至字符。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p>用日期过滤 <code class="docutils literal notranslate"><span class="pre">DateTimeField</span></code> 不会包括最后一天的项目，因为界限被解释为“给定日期的 0 点”。如果 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 是一个 <code class="docutils literal notranslate"><span class="pre">DateTimeField</span></code>，上面的表达式就会变成这个 SQL：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">pub_date</span> <span class="k">BETWEEN</span> <span class="s1">&#39;2005-01-01 00:00:00&#39;</span> <span class="k">and</span> <span class="s1">&#39;2005-03-31 00:00:00&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p class="last">一般来说，你不能把日期和日期时间混在一起。</p>
</div>
</div>
<div class="section" id="s-date">
<span id="s-std:fieldlookup-date"></span><span id="date"></span><span id="std:fieldlookup-date"></span><h4><code class="docutils literal notranslate"><span class="pre">date</span></code><a class="headerlink" href="#date" title="永久链接至标题">¶</a></h4>
<p>对于日期时间字段，将值投射为日期。允许链接其他字段的查找。取一个日期值。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__date</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__date__gt</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
<p>（由于不同的数据库引擎对相关查询的实现各不相同，因此本次查询不包含等效的 SQL 代码片段）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，字段在过滤前会被转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-year">
<span id="s-std:fieldlookup-year"></span><span id="year"></span><span id="std:fieldlookup-year"></span><h4><code class="docutils literal notranslate"><span class="pre">year</span></code><a class="headerlink" href="#year" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，精确匹配年份。允许链接其他字段的查询。取整数年。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="mi">2005</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__year__gte</span><span class="o">=</span><span class="mi">2005</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">pub_date</span> <span class="k">BETWEEN</span> <span class="s1">&#39;2005-01-01&#39;</span> <span class="k">AND</span> <span class="s1">&#39;2005-12-31&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">pub_date</span> <span class="o">&gt;=</span> <span class="s1">&#39;2005-01-01&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-iso-year">
<span id="s-std:fieldlookup-iso_year"></span><span id="iso-year"></span><span id="std:fieldlookup-iso_year"></span><h4><code class="docutils literal notranslate"><span class="pre">iso_year</span></code><a class="headerlink" href="#iso-year" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，精确的 ISO 8601 周号年份匹配。允许链接其他字段的查询。取整数年。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__iso_year</span><span class="o">=</span><span class="mi">2005</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__iso_year__gte</span><span class="o">=</span><span class="mi">2005</span><span class="p">)</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-month">
<span id="s-std:fieldlookup-month"></span><span id="month"></span><span id="std:fieldlookup-month"></span><h4><code class="docutils literal notranslate"><span class="pre">month</span></code><a class="headerlink" href="#month" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，精确的月份匹配。允许链接其他字段的查询。取整数 1（1 月）到 12（12 月）。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__month</span><span class="o">=</span><span class="mi">12</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__month__gte</span><span class="o">=</span><span class="mi">6</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;month&#39;</span> <span class="k">FROM</span> <span class="n">pub_date</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;12&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;month&#39;</span> <span class="k">FROM</span> <span class="n">pub_date</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="s1">&#39;6&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-day">
<span id="s-std:fieldlookup-day"></span><span id="day"></span><span id="std:fieldlookup-day"></span><h4><code class="docutils literal notranslate"><span class="pre">day</span></code><a class="headerlink" href="#day" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，精确匹配日期。允许链接其他字段的查询。取整数日。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__day</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__day__gte</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;day&#39;</span> <span class="k">FROM</span> <span class="n">pub_date</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;3&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;day&#39;</span> <span class="k">FROM</span> <span class="n">pub_date</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="s1">&#39;3&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>请注意，这将匹配任何带有 pub_date 的月份第三天的记录，如 1 月 3 日，7 月 3 日等。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-week">
<span id="s-std:fieldlookup-week"></span><span id="week"></span><span id="std:fieldlookup-week"></span><h4><code class="docutils literal notranslate"><span class="pre">week</span></code><a class="headerlink" href="#week" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，根据 <a class="reference external" href="https://en.wikipedia.org/wiki/ISO-8601">ISO-8601</a> ，返回星期号（1-52 或 53），即星期从星期一开始，第一周包含一年的第一个星期四。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__week</span><span class="o">=</span><span class="mi">52</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__week__gte</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> <span class="n">pub_date__week__lte</span><span class="o">=</span><span class="mi">38</span><span class="p">)</span>
</pre></div>
</div>
<p>（由于不同的数据库引擎对相关查询的实现各不相同，因此本次查询不包含等效的 SQL 代码片段）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-week-day">
<span id="s-std:fieldlookup-week_day"></span><span id="week-day"></span><span id="std:fieldlookup-week_day"></span><h4><code class="docutils literal notranslate"><span class="pre">week_day</span></code><a class="headerlink" href="#week-day" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，“星期几”匹配。允许链接其他字段的查询。</p>
<p>从 1（星期日）到 7（星期六）取一个整数值，代表一周的一天。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__week_day</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__week_day__gte</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
</div>
<p>（由于不同的数据库引擎对相关查询的实现各不相同，因此本次查询不包含等效的 SQL 代码片段）。</p>
<p>请注意，这将匹配任何带有 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 的记录，这些记录都是在星期一（一周的第 2 天）发生的，不管它发生在哪一年哪一月。周日的索引，第 1 天是周日，第 7 天是周六。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-iso-week-day">
<span id="s-std:fieldlookup-iso_week_day"></span><span id="iso-week-day"></span><span id="std:fieldlookup-iso_week_day"></span><h4><code class="docutils literal notranslate"><span class="pre">iso_week_day</span></code><a class="headerlink" href="#iso-week-day" title="永久链接至标题">¶</a></h4>
<div class="versionadded">
<span class="title">New in Django 3.1.</span> </div>
<p>对于日期和日期时间字段，精确匹配 ISO 8601 星期几。允许链接其他字段的查询。</p>
<p>取一个整数值，代表一周的 1（星期一）到 7（星期日）。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__iso_week_day</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__iso_week_day__gte</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>（由于不同的数据库引擎对相关查询的实现各不相同，因此本次查询不包含等效的 SQL 代码片段）。</p>
<p>请注意，这将匹配任何带有 <code class="docutils literal notranslate"><span class="pre">pub_date</span></code> 的记录，这些记录都是在星期一（一周的第 1 天）发生的，不管它发生在哪个月或哪个年。周日的索引是第 1 天是星期一，第 7 天是星期天。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-quarter">
<span id="s-std:fieldlookup-quarter"></span><span id="quarter"></span><span id="std:fieldlookup-quarter"></span><h4><code class="docutils literal notranslate"><span class="pre">quarter</span></code><a class="headerlink" href="#quarter" title="永久链接至标题">¶</a></h4>
<p>对于日期和日期时间字段，“一年的四分之一”匹配。允许链接额外的字段查找。取 1 到 4 之间的整数值，代表一年中的季度。</p>
<p>检索第二季度（4 月 1 日至 6 月 30 日）的条目示例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__quarter</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
</div>
<p>（由于不同的数据库引擎对相关查询的实现各不相同，因此本次查询不包含等效的 SQL 代码片段）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-time">
<span id="s-std:fieldlookup-time"></span><span id="time"></span><span id="std:fieldlookup-time"></span><h4><code class="docutils literal notranslate"><span class="pre">time</span></code><a class="headerlink" href="#time" title="永久链接至标题">¶</a></h4>
<p>对于日期时间字段，将其值强制转换为时间。允许链式附加字段查找。取一个 <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.time" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.time</span></code></a> 的值。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__time</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="mi">30</span><span class="p">))</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__time__range</span><span class="o">=</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="mi">8</span><span class="p">),</span> <span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="mi">17</span><span class="p">)))</span>
</pre></div>
</div>
<p>（由于不同的数据库引擎对相关查询的实现各不相同，因此本次查询不包含等效的 SQL 代码片段）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，字段在过滤前会被转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-hour">
<span id="s-std:fieldlookup-hour"></span><span id="hour"></span><span id="std:fieldlookup-hour"></span><h4><code class="docutils literal notranslate"><span class="pre">hour</span></code><a class="headerlink" href="#hour" title="永久链接至标题">¶</a></h4>
<p>对于日期时间和时间字段，精确的小时匹配。允许链式查找其他字段。取 0 到 23 之间的整数。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">timestamp__hour</span><span class="o">=</span><span class="mi">23</span><span class="p">)</span>
<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">time__hour</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">timestamp__hour__gte</span><span class="o">=</span><span class="mi">12</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;hour&#39;</span> <span class="k">FROM</span> <span class="k">timestamp</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;23&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;hour&#39;</span> <span class="k">FROM</span> <span class="k">time</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;5&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;hour&#39;</span> <span class="k">FROM</span> <span class="k">timestamp</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="s1">&#39;12&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-minute">
<span id="s-std:fieldlookup-minute"></span><span id="minute"></span><span id="std:fieldlookup-minute"></span><h4><code class="docutils literal notranslate"><span class="pre">minute</span></code><a class="headerlink" href="#minute" title="永久链接至标题">¶</a></h4>
<p>对于日期时间和时间字段，精确的分钟匹配。允许链式查找其他字段。取 0 到 59 之间的整数。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">timestamp__minute</span><span class="o">=</span><span class="mi">29</span><span class="p">)</span>
<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">time__minute</span><span class="o">=</span><span class="mi">46</span><span class="p">)</span>
<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">timestamp__minute__gte</span><span class="o">=</span><span class="mi">29</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;minute&#39;</span> <span class="k">FROM</span> <span class="k">timestamp</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;29&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;minute&#39;</span> <span class="k">FROM</span> <span class="k">time</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;46&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;minute&#39;</span> <span class="k">FROM</span> <span class="k">timestamp</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="s1">&#39;29&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-second">
<span id="s-std:fieldlookup-second"></span><span id="second"></span><span id="std:fieldlookup-second"></span><h4><code class="docutils literal notranslate"><span class="pre">second</span></code><a class="headerlink" href="#second" title="永久链接至标题">¶</a></h4>
<p>对于日期时间和时间字段，完全秒配。允许链式查找其他字段。取 0 到 59 之间的整数。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">timestamp__second</span><span class="o">=</span><span class="mi">31</span><span class="p">)</span>
<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">time__second</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">Event</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">timestamp__second__gte</span><span class="o">=</span><span class="mi">31</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;second&#39;</span> <span class="k">FROM</span> <span class="k">timestamp</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;31&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;second&#39;</span> <span class="k">FROM</span> <span class="k">time</span><span class="p">)</span> <span class="o">=</span> <span class="s1">&#39;2&#39;</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="k">EXTRACT</span><span class="p">(</span><span class="s1">&#39;second&#39;</span> <span class="k">FROM</span> <span class="k">timestamp</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="s1">&#39;31&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>（确切的 SQL 语法因每个数据库引擎而异）。</p>
<p>当 <a class="reference internal" href="../settings.html#std:setting-USE_TZ"><code class="xref std std-setting docutils literal notranslate"><span class="pre">USE_TZ</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时，日期时间字段会在过滤前转换为当前时区。这需要 <a class="reference internal" href="#database-time-zone-definitions"><span class="std std-ref">数据库中的时区定义</span></a>。</p>
</div>
<div class="section" id="s-isnull">
<span id="s-std:fieldlookup-isnull"></span><span id="isnull"></span><span id="std:fieldlookup-isnull"></span><h4><code class="docutils literal notranslate"><span class="pre">isnull</span></code><a class="headerlink" href="#isnull" title="永久链接至标题">¶</a></h4>
<p>取 <code class="docutils literal notranslate"><span class="pre">True</span></code> 或 <code class="docutils literal notranslate"><span class="pre">False</span></code>，分别对应 <code class="docutils literal notranslate"><span class="pre">IS</span> <span class="pre">NULL</span></code> 和 <code class="docutils literal notranslate"><span class="pre">IS</span> <span class="pre">NOT</span> <span class="pre">NULL</span></code> 的 SQL 查询。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pub_date__isnull</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">pub_date</span> <span class="k">IS</span> <span class="k">NULL</span><span class="p">;</span>
</pre></div>
</div>
<div class="deprecated">
<p><span class="versionmodified">3.1 版后已移除: </span>使用非布尔值作为右手边的值已经被废弃，请使用 <code class="docutils literal notranslate"><span class="pre">True</span></code> 或 <code class="docutils literal notranslate"><span class="pre">False</span></code> 代替。在 Django 4.0 中，将引发异常。</p>
</div>
</div>
<div class="section" id="s-regex">
<span id="s-std:fieldlookup-regex"></span><span id="regex"></span><span id="std:fieldlookup-regex"></span><h4><code class="docutils literal notranslate"><span class="pre">regex</span></code><a class="headerlink" href="#regex" title="永久链接至标题">¶</a></h4>
<p>区分大小写的正则表达式匹配。</p>
<p>正则表达式语法是使用中的数据库后端的语法。对于没有内置正则表达式支持的 SQLite 来说，这个功能是由（Python）用户定义的 REGEXP 函数提供的，因此正则表达式语法是 Python 的 <code class="docutils literal notranslate"><span class="pre">re</span></code> 模块的语法。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">title__regex</span><span class="o">=</span><span class="sa">r</span><span class="s1">&#39;^(An?|The) +&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">title</span> <span class="n">REGEXP</span> <span class="nb">BINARY</span> <span class="s1">&#39;^(An?|The) +&#39;</span><span class="p">;</span> <span class="c1">-- MySQL</span>

<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">REGEXP_LIKE</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="s1">&#39;^(An?|The) +&#39;</span><span class="p">,</span> <span class="s1">&#39;c&#39;</span><span class="p">);</span> <span class="c1">-- Oracle</span>

<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">title</span> <span class="o">~</span> <span class="s1">&#39;^(An?|The) +&#39;</span><span class="p">;</span> <span class="c1">-- PostgreSQL</span>

<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">title</span> <span class="n">REGEXP</span> <span class="s1">&#39;^(An?|The) +&#39;</span><span class="p">;</span> <span class="c1">-- SQLite</span>
</pre></div>
</div>
<p>建议使用原始字符串（例如，用 <code class="docutils literal notranslate"><span class="pre">r'foo'</span></code> 代替 <code class="docutils literal notranslate"><span class="pre">'foo'</span></code>）来传递正则表达式语法。</p>
</div>
<div class="section" id="s-iregex">
<span id="s-std:fieldlookup-iregex"></span><span id="iregex"></span><span id="std:fieldlookup-iregex"></span><h4><code class="docutils literal notranslate"><span class="pre">iregex</span></code><a class="headerlink" href="#iregex" title="永久链接至标题">¶</a></h4>
<p>不区分大小写的正则表达式匹配。</p>
<p>举例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">title__iregex</span><span class="o">=</span><span class="sa">r</span><span class="s1">&#39;^(an?|the) +&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQL 等价于：</p>
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">title</span> <span class="n">REGEXP</span> <span class="s1">&#39;^(an?|the) +&#39;</span><span class="p">;</span> <span class="c1">-- MySQL</span>

<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">REGEXP_LIKE</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="s1">&#39;^(an?|the) +&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">);</span> <span class="c1">-- Oracle</span>

<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">title</span> <span class="o">~*</span> <span class="s1">&#39;^(an?|the) +&#39;</span><span class="p">;</span> <span class="c1">-- PostgreSQL</span>

<span class="k">SELECT</span> <span class="p">...</span> <span class="k">WHERE</span> <span class="n">title</span> <span class="n">REGEXP</span> <span class="s1">&#39;(?i)^(an?|the) +&#39;</span><span class="p">;</span> <span class="c1">-- SQLite</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="s-aggregation-functions">
<span id="s-id5"></span><span id="aggregation-functions"></span><span id="id5"></span><h3>聚合函数<a class="headerlink" href="#aggregation-functions" title="永久链接至标题">¶</a></h3>
<p>Django 在 <code class="docutils literal notranslate"><span class="pre">django.db.models</span></code> 模块中提供了以下聚合函数。关于如何使用这些聚合函数的细节，请参见 <a class="reference internal" href="../../topics/db/aggregation.html"><span class="doc">关于聚合的主题指南</span></a>。参见 <a class="reference internal" href="expressions.html#django.db.models.Aggregate" title="django.db.models.Aggregate"><code class="xref py py-class docutils literal notranslate"><span class="pre">Aggregate</span></code></a> 文档，了解如何创建你的聚合函数。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">SQLite 无法处理日期／时间字段的聚合。这是因为 SQLite 中没有原生的日期／时间字段，而 Django 目前使用文本字段来模拟这些功能。试图在 SQLite 中使用日期／时间字段上的聚合将引发 <code class="docutils literal notranslate"><span class="pre">NotSupportedError</span></code>。</p>
</div>
<div class="admonition-note admonition">
<p class="first admonition-title">注解</p>
<p class="last">当与空的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 一起使用时，聚合函数返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。例如，如果 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 不包含任何条目，<code class="docutils literal notranslate"><span class="pre">Sum</span></code> 聚合函数返回 <code class="docutils literal notranslate"><span class="pre">None</span></code> 而不是 <code class="docutils literal notranslate"><span class="pre">0</span></code>。一个例外是 <code class="docutils literal notranslate"><span class="pre">Count</span></code>，如果 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 为空，则返回 <code class="docutils literal notranslate"><span class="pre">0</span></code>。</p>
</div>
<p>所有聚合体都有以下共同的参数：</p>
<div class="section" id="s-expressions">
<span id="expressions"></span><h4><code class="docutils literal notranslate"><span class="pre">expressions</span></code><a class="headerlink" href="#expressions" title="永久链接至标题">¶</a></h4>
<p>Strings that reference fields on the model, transforms of the field, or
<a class="reference internal" href="expressions.html"><span class="doc">query expressions</span></a>.</p>
<div class="versionchanged">
<span class="title">Changed in Django 3.2:</span> <p>Support for transforms of the field was added.</p>
</div>
</div>
<div class="section" id="s-output-field">
<span id="output-field"></span><h4><code class="docutils literal notranslate"><span class="pre">output_field</span></code><a class="headerlink" href="#output-field" title="永久链接至标题">¶</a></h4>
<p>一个可选的参数，表示返回值的 <a class="reference internal" href="fields.html"><span class="doc">模型字段</span></a></p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">当组合多个字段类型时，Django 只能在所有字段类型相同的情况下确定 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>。否则，你必须自己提供 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>。</p>
</div>
</div>
<div class="section" id="s-aggregate-filter">
<span id="s-id6"></span><span id="aggregate-filter"></span><span id="id6"></span><h4><code class="docutils literal notranslate"><span class="pre">filter</span></code><a class="headerlink" href="#aggregate-filter" title="永久链接至标题">¶</a></h4>
<p>一个可选的 <a class="reference internal" href="#django.db.models.Q" title="django.db.models.Q"><code class="xref py py-class docutils literal notranslate"><span class="pre">Q</span> <span class="pre">对象</span></code></a>，用于过滤被聚合的行。</p>
<p>参见 <a class="reference internal" href="conditional-expressions.html#conditional-aggregation"><span class="std std-ref">条件聚合</span></a> 和 <a class="reference internal" href="../../topics/db/aggregation.html#filtering-on-annotations"><span class="std std-ref">过滤注解</span></a> 的用法示例。</p>
</div>
<div class="section" id="s-id7">
<span id="id7"></span><h4><code class="docutils literal notranslate"><span class="pre">**extra</span></code><a class="headerlink" href="#id7" title="永久链接至标题">¶</a></h4>
<p>关键字参数，可以为聚合生成的 SQL 提供额外的上下文。</p>
</div>
<div class="section" id="s-avg">
<span id="avg"></span><h4><code class="docutils literal notranslate"><span class="pre">Avg</span></code><a class="headerlink" href="#avg" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.Avg">
<em class="property">class </em><code class="descname">Avg</code>(<em>expression</em>, <em>output_field=None</em>, <em>distinct=False</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.Avg" title="永久链接至目标">¶</a></dt>
<dd><p>返回给定表达式的平均值，除非指定不同的 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>，否则必须是数值。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__avg</span></code></li>
<li>返回类型。如果输入是 <code class="docutils literal notranslate"><span class="pre">int</span></code>，则返回 <code class="docutils literal notranslate"><span class="pre">float</span></code>，否则与输入字段相同，如果提供了 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>，则返回 <a href="#id1"><span class="problematic" id="id2">``</span></a>output_field`。</li>
</ul>
<p>包含一个可选参数：</p>
<dl class="attribute">
<dt id="django.db.models.Avg.distinct">
<code class="descname">distinct</code><a class="headerlink" href="#django.db.models.Avg.distinct" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <code class="docutils literal notranslate"><span class="pre">distinct=True</span></code>，<code class="docutils literal notranslate"><span class="pre">Avg</span></code> 返回非重复值的平均值。这相当于 SQL 中的 <code class="docutils literal notranslate"><span class="pre">AVG(DISTINCT</span> <span class="pre">&lt;field&gt;)</span></code>。默认值是 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
</dd></dl>

</dd></dl>

</div>
<div class="section" id="s-id8">
<span id="id8"></span><h4><code class="docutils literal notranslate"><span class="pre">Count</span></code><a class="headerlink" href="#id8" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.Count">
<em class="property">class </em><code class="descname">Count</code>(<em>expression</em>, <em>distinct=False</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.Count" title="永久链接至目标">¶</a></dt>
<dd><p>返回通过提供的表达式关联的对象数量。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__count</span></code></li>
<li>返回类型：<code class="docutils literal notranslate"><span class="pre">int</span></code></li>
</ul>
<p>包含一个可选参数：</p>
<dl class="attribute">
<dt id="django.db.models.Count.distinct">
<code class="descname">distinct</code><a class="headerlink" href="#django.db.models.Count.distinct" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <code class="docutils literal notranslate"><span class="pre">distinct=True</span></code>，计数将只包括非重复的实例。这相当于 SQL 中的 <code class="docutils literal notranslate"><span class="pre">COUNT(DISTINCT</span> <span class="pre">&lt;field&gt;)</span></code>。默认值是 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
</dd></dl>

</dd></dl>

</div>
<div class="section" id="s-max">
<span id="max"></span><h4><code class="docutils literal notranslate"><span class="pre">Max</span></code><a class="headerlink" href="#max" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.Max">
<em class="property">class </em><code class="descname">Max</code>(<em>expression</em>, <em>output_field=None</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.Max" title="永久链接至目标">¶</a></dt>
<dd><p>返回给定表达式的最大值。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__max</span></code></li>
<li>返回类型：与输入字段相同，或 <code class="docutils literal notranslate"><span class="pre">output_field</span></code> 如果有。</li>
</ul>
</dd></dl>

</div>
<div class="section" id="s-min">
<span id="min"></span><h4><code class="docutils literal notranslate"><span class="pre">Min</span></code><a class="headerlink" href="#min" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.Min">
<em class="property">class </em><code class="descname">Min</code>(<em>expression</em>, <em>output_field=None</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.Min" title="永久链接至目标">¶</a></dt>
<dd><p>返回给定表达式的最小值。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__min</span></code></li>
<li>返回类型：与输入字段相同，或 <code class="docutils literal notranslate"><span class="pre">output_field</span></code> 如果有。</li>
</ul>
</dd></dl>

</div>
<div class="section" id="s-stddev">
<span id="stddev"></span><h4><code class="docutils literal notranslate"><span class="pre">StdDev</span></code><a class="headerlink" href="#stddev" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.StdDev">
<em class="property">class </em><code class="descname">StdDev</code>(<em>expression</em>, <em>output_field=None</em>, <em>sample=False</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.StdDev" title="永久链接至目标">¶</a></dt>
<dd><p>返回给定表达式中数据的标准差。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__stddev</span></code></li>
<li>返回类型。如果输入是 <code class="docutils literal notranslate"><span class="pre">int</span></code>，则返回 <code class="docutils literal notranslate"><span class="pre">float</span></code>，否则与输入字段相同，如果提供了 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>，则返回 <a href="#id1"><span class="problematic" id="id2">``</span></a>output_field`。</li>
</ul>
<p>包含一个可选参数：</p>
<dl class="attribute">
<dt id="django.db.models.StdDev.sample">
<code class="descname">sample</code><a class="headerlink" href="#django.db.models.StdDev.sample" title="永久链接至目标">¶</a></dt>
<dd><p>默认情况下，<code class="docutils literal notranslate"><span class="pre">StdDev</span></code> 返回总体标准差。 但是，如果 <code class="docutils literal notranslate"><span class="pre">sample=True</span></code>，则返回值为样本标准差。</p>
</dd></dl>

</dd></dl>

</div>
<div class="section" id="s-sum">
<span id="sum"></span><h4><code class="docutils literal notranslate"><span class="pre">Sum</span></code><a class="headerlink" href="#sum" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.Sum">
<em class="property">class </em><code class="descname">Sum</code>(<em>expression</em>, <em>output_field=None</em>, <em>distinct=False</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.Sum" title="永久链接至目标">¶</a></dt>
<dd><p>计算给定表达式的所有值的总和。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__sum</span></code></li>
<li>返回类型：与输入字段相同，或 <code class="docutils literal notranslate"><span class="pre">output_field</span></code> 如果有。</li>
</ul>
<p>包含一个可选参数：</p>
<dl class="attribute">
<dt id="django.db.models.Sum.distinct">
<code class="descname">distinct</code><a class="headerlink" href="#django.db.models.Sum.distinct" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <code class="docutils literal notranslate"><span class="pre">distinct=True</span></code>，则 <code class="docutils literal notranslate"><span class="pre">Sum</span></code> 返回非重复值的总和。 这与 SQL 的 <code class="docutils literal notranslate"><span class="pre">SUM(DISTINCT</span> <span class="pre">&lt;field&gt;)</span></code> 等效。 默认值为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
</dd></dl>

</dd></dl>

</div>
<div class="section" id="s-variance">
<span id="variance"></span><h4><code class="docutils literal notranslate"><span class="pre">Variance</span></code><a class="headerlink" href="#variance" title="永久链接至标题">¶</a></h4>
<dl class="class">
<dt id="django.db.models.Variance">
<em class="property">class </em><code class="descname">Variance</code>(<em>expression</em>, <em>output_field=None</em>, <em>sample=False</em>, <em>filter=None</em>, <em>**extra</em>)<a class="headerlink" href="#django.db.models.Variance" title="永久链接至目标">¶</a></dt>
<dd><p>返回给定表达式中数据的方差。</p>
<ul class="simple">
<li>默认别名：<code class="docutils literal notranslate"><span class="pre">&lt;field&gt;__variance</span></code></li>
<li>返回类型。如果输入是 <code class="docutils literal notranslate"><span class="pre">int</span></code>，则返回 <code class="docutils literal notranslate"><span class="pre">float</span></code>，否则与输入字段相同，如果提供了 <code class="docutils literal notranslate"><span class="pre">output_field</span></code>，则返回 <a href="#id1"><span class="problematic" id="id2">``</span></a>output_field`。</li>
</ul>
<p>包含一个可选参数：</p>
<dl class="attribute">
<dt id="django.db.models.Variance.sample">
<code class="descname">sample</code><a class="headerlink" href="#django.db.models.Variance.sample" title="永久链接至目标">¶</a></dt>
<dd><p>默认情况下， <code class="docutils literal notranslate"><span class="pre">Variance</span></code> 返回总体方差。 但是，如果 <code class="docutils literal notranslate"><span class="pre">sample=True</span></code>，则返回值将是样本方差。</p>
</dd></dl>

</dd></dl>

</div>
</div>
</div>
<div class="section" id="s-query-related-tools">
<span id="query-related-tools"></span><h2>查询相关工具<a class="headerlink" href="#query-related-tools" title="永久链接至标题">¶</a></h2>
<p>本节提供了与查询相关的工具的参考资料，其他地方没有记载。</p>
<div class="section" id="s-q-objects">
<span id="q-objects"></span><h3><code class="docutils literal notranslate"><span class="pre">Q()</span></code> 对象<a class="headerlink" href="#q-objects" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="django.db.models.Q">
<em class="property">class </em><code class="descname">Q</code><a class="headerlink" href="#django.db.models.Q" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">Q()</span></code> 对象表示一个 SQL 条件，它可以用于数据库相关的操作。它类似于 <a class="reference internal" href="expressions.html#django.db.models.F" title="django.db.models.F"><code class="xref py py-class docutils literal notranslate"><span class="pre">F()</span></code></a> 对象如何表示一个模型字段或注解的值。它们使得定义和重用条件成为可能，并使用诸如 <code class="docutils literal notranslate"><span class="pre">|</span></code> （<code class="docutils literal notranslate"><span class="pre">OR</span></code>）和 <code class="docutils literal notranslate"><span class="pre">&amp;</span></code> （<code class="docutils literal notranslate"><span class="pre">AND</span></code>）等运算符将它们组合起来。见 <a class="reference internal" href="../../topics/db/queries.html#complex-lookups-with-q"><span class="std std-ref">通过 Q 对象完成复杂查询</span></a>。</p>
</div>
<div class="section" id="s-prefetch-objects">
<span id="prefetch-objects"></span><h3><code class="docutils literal notranslate"><span class="pre">Prefetch()</span></code> 对象<a class="headerlink" href="#prefetch-objects" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="django.db.models.Prefetch">
<em class="property">class </em><code class="descname">Prefetch</code>(<em>lookup</em>, <em>queryset=None</em>, <em>to_attr=None</em>)<a class="headerlink" href="#django.db.models.Prefetch" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">Prefetch()</span></code> 对象可以用来控制 <code class="xref py py-meth docutils literal notranslate"><span class="pre">prefetch_related()</span></code> 的操作。</p>
<p><code class="docutils literal notranslate"><span class="pre">lookup</span></code> 参数描述了要遵循的关系，并且与传递给 <a class="reference internal" href="#django.db.models.query.QuerySet.prefetch_related" title="django.db.models.query.QuerySet.prefetch_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">prefetch_related()</span></code></a> 的基于字符串的查找相同。 例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Prefetch</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;choice_set&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">get</span><span class="p">()</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">&lt;QuerySet [&lt;Choice: Not much&gt;, &lt;Choice: The sky&gt;, &lt;Choice: Just hacking again&gt;]&gt;</span>
<span class="go"># This will only execute two queries regardless of the number of Question</span>
<span class="go"># and Choice objects.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;choice_set&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">&lt;QuerySet [&lt;Question: What&#39;s up?&gt;]&gt;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">queryset</span></code> 参数为给定的查询提供基本的 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>。 这对于进一步过滤预取操作或从预取关系中调用 <a class="reference internal" href="#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> 很有用，从而进一步减少了查询数量：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">voted_choices</span> <span class="o">=</span> <span class="n">Choice</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">votes__gt</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">voted_choices</span>
<span class="go">&lt;QuerySet [&lt;Choice: The sky&gt;]&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">prefetch</span> <span class="o">=</span> <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;choice_set&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">voted_choices</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="n">prefetch</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">()</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">&lt;QuerySet [&lt;Choice: The sky&gt;]&gt;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">to_attr</span></code> 参数将预取操作的结果设置为自定义属性：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">prefetch</span> <span class="o">=</span> <span class="n">Prefetch</span><span class="p">(</span><span class="s1">&#39;choice_set&#39;</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">voted_choices</span><span class="p">,</span> <span class="n">to_attr</span><span class="o">=</span><span class="s1">&#39;voted_choices&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="n">prefetch</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">()</span><span class="o">.</span><span class="n">voted_choices</span>
<span class="go">[&lt;Choice: The sky&gt;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">prefetch_related</span><span class="p">(</span><span class="n">prefetch</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">()</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">&lt;QuerySet [&lt;Choice: Not much&gt;, &lt;Choice: The sky&gt;, &lt;Choice: Just hacking again&gt;]&gt;</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">当使用 <code class="docutils literal notranslate"><span class="pre">to_attr</span></code> 时，预取结果存储在列表中。 与传统的 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 调用相比，这可以显着提高速度，传统的 <code class="docutils literal notranslate"><span class="pre">prefetch_related</span></code> 调用将缓存的结果存储在 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 实例中。</p>
</div>
</div>
<div class="section" id="s-prefetch-related-objects">
<span id="prefetch-related-objects"></span><h3><code class="docutils literal notranslate"><span class="pre">prefetch_related_objects()</span></code><a class="headerlink" href="#prefetch-related-objects" title="永久链接至标题">¶</a></h3>
<dl class="function">
<dt id="django.db.models.prefetch_related_objects">
<code class="descname">prefetch_related_objects</code>(<em>model_instances</em>, <em>*related_lookups</em>)<a class="headerlink" href="#django.db.models.prefetch_related_objects" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>在作为模型实例的可迭代对象上预取给定的查找。这在接收模型实例列表而不是 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的代码中很有用；例如，从缓存中获取模型或手动实例化它们时。</p>
<p>传递一个作为模型实例的可迭代对象（必须都是同一个类）和你想预取的查找或 <a class="reference internal" href="#django.db.models.Prefetch" title="django.db.models.Prefetch"><code class="xref py py-class docutils literal notranslate"><span class="pre">Prefetch</span></code></a> 对象。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">prefetch_related_objects</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">restaurants</span> <span class="o">=</span> <span class="n">fetch_top_restaurants_from_cache</span><span class="p">()</span>  <span class="c1"># A list of Restaurants</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">prefetch_related_objects</span><span class="p">(</span><span class="n">restaurants</span><span class="p">,</span> <span class="s1">&#39;pizzas__toppings&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>当使用 <code class="docutils literal notranslate"><span class="pre">prefetch_related_objects</span></code> 的多个数据库时，预取查询将使用与模型实例相关的数据库。这可以通过在相关查找中使用自定义查询集来覆盖。</p>
</div>
<div class="section" id="s-filteredrelation-objects">
<span id="filteredrelation-objects"></span><h3><code class="docutils literal notranslate"><span class="pre">FilteredRelation()</span></code> 对象<a class="headerlink" href="#filteredrelation-objects" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="django.db.models.FilteredRelation">
<em class="property">class </em><code class="descname">FilteredRelation</code>(<em>relation_name</em>, <em>*</em>, <em>condition=Q()</em>)<a class="headerlink" href="#django.db.models.FilteredRelation" title="永久链接至目标">¶</a></dt>
<dd><dl class="attribute">
<dt id="django.db.models.FilteredRelation.relation_name">
<code class="descname">relation_name</code><a class="headerlink" href="#django.db.models.FilteredRelation.relation_name" title="永久链接至目标">¶</a></dt>
<dd><p>你想过滤关系的字段名。</p>
</dd></dl>

<dl class="attribute">
<dt id="django.db.models.FilteredRelation.condition">
<code class="descname">condition</code><a class="headerlink" href="#django.db.models.FilteredRelation.condition" title="永久链接至目标">¶</a></dt>
<dd><p>一个 <a class="reference internal" href="#django.db.models.Q" title="django.db.models.Q"><code class="xref py py-class docutils literal notranslate"><span class="pre">Q</span></code></a> 对象来控制过滤。</p>
</dd></dl>

</dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">FilteredRelation</span></code> 与 <a class="reference internal" href="#django.db.models.query.QuerySet.annotate" title="django.db.models.query.QuerySet.annotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">annotate()</span></code></a> 一起使用，在执行 <code class="docutils literal notranslate"><span class="pre">JOIN</span></code> 时创建一个 <code class="docutils literal notranslate"><span class="pre">ON</span></code> 子句。它不作用于默认的关系，而是作用于注解名称（下面例子中的 <code class="docutils literal notranslate"><span class="pre">pizzas_vegetarian</span></code>）。</p>
<p>例如，要找到名称中含有 <code class="docutils literal notranslate"><span class="pre">'mozzarella'</span></code> 的素食披萨的餐馆：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">FilteredRelation</span><span class="p">,</span> <span class="n">Q</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span>
<span class="gp">... </span>   <span class="n">pizzas_vegetarian</span><span class="o">=</span><span class="n">FilteredRelation</span><span class="p">(</span>
<span class="gp">... </span>       <span class="s1">&#39;pizzas&#39;</span><span class="p">,</span> <span class="n">condition</span><span class="o">=</span><span class="n">Q</span><span class="p">(</span><span class="n">pizzas__vegetarian</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="gp">... </span>   <span class="p">),</span>
<span class="gp">... </span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pizzas_vegetarian__name__icontains</span><span class="o">=</span><span class="s1">&#39;mozzarella&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>如果有大量的披萨，这个查询集的性能更好：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Restaurant</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">pizzas__vegetarian</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">pizzas__name__icontains</span><span class="o">=</span><span class="s1">&#39;mozzarella&#39;</span><span class="p">,</span>
<span class="gp">... </span><span class="p">)</span>
</pre></div>
</div>
<p>因为第一个查询集的 <code class="docutils literal notranslate"><span class="pre">WHERE</span></code> 子句中的过滤只对素食披萨进行操作。</p>
<p><code class="docutils literal notranslate"><span class="pre">FilteredRelation</span></code> 不支持：</p>
<ul class="simple">
<li><a class="reference internal" href="#django.db.models.query.QuerySet.only" title="django.db.models.query.QuerySet.only"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.only()</span></code></a> 和 <a class="reference internal" href="#django.db.models.query.QuerySet.prefetch_related" title="django.db.models.query.QuerySet.prefetch_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">prefetch_related()</span></code></a>。</li>
<li>一个从父模型继承的 <a class="reference internal" href="../contrib/contenttypes.html#django.contrib.contenttypes.fields.GenericForeignKey" title="django.contrib.contenttypes.fields.GenericForeignKey"><code class="xref py py-class docutils literal notranslate"><span class="pre">GenericForeignKey</span></code></a>。</li>
</ul>
<div class="versionchanged">
<span class="title">Changed in Django 3.2:</span> <p>Support for nested relations was added.</p>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> API 参考</a><ul>
<li><a class="reference internal" href="#when-querysets-are-evaluated">什么时候 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 被执行</a><ul>
<li><a class="reference internal" href="#pickling-querysets">Pickle 序列化 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#queryset-api"><code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> API</a><ul>
<li><a class="reference internal" href="#methods-that-return-new-querysets">返回新 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的方法</a><ul>
<li><a class="reference internal" href="#filter"><code class="docutils literal notranslate"><span class="pre">filter()</span></code></a></li>
<li><a class="reference internal" href="#exclude"><code class="docutils literal notranslate"><span class="pre">exclude()</span></code></a></li>
<li><a class="reference internal" href="#annotate"><code class="docutils literal notranslate"><span class="pre">annotate()</span></code></a></li>
<li><a class="reference internal" href="#alias"><code class="docutils literal notranslate"><span class="pre">alias()</span></code></a></li>
<li><a class="reference internal" href="#order-by"><code class="docutils literal notranslate"><span class="pre">order_by()</span></code></a></li>
<li><a class="reference internal" href="#reverse">reverse()</a></li>
<li><a class="reference internal" href="#distinct"><code class="docutils literal notranslate"><span class="pre">distinct()</span></code></a></li>
<li><a class="reference internal" href="#values"><code class="docutils literal notranslate"><span class="pre">values()</span></code></a></li>
<li><a class="reference internal" href="#values-list"><code class="docutils literal notranslate"><span class="pre">values_list()</span></code></a></li>
<li><a class="reference internal" href="#dates"><code class="docutils literal notranslate"><span class="pre">dates()</span></code></a></li>
<li><a class="reference internal" href="#datetimes"><code class="docutils literal notranslate"><span class="pre">datetimes()</span></code></a></li>
<li><a class="reference internal" href="#none"><code class="docutils literal notranslate"><span class="pre">none()</span></code></a></li>
<li><a class="reference internal" href="#all"><code class="docutils literal notranslate"><span class="pre">all()</span></code></a></li>
<li><a class="reference internal" href="#union"><code class="docutils literal notranslate"><span class="pre">union()</span></code></a></li>
<li><a class="reference internal" href="#intersection"><code class="docutils literal notranslate"><span class="pre">intersection()</span></code></a></li>
<li><a class="reference internal" href="#difference"><code class="docutils literal notranslate"><span class="pre">difference()</span></code></a></li>
<li><a class="reference internal" href="#select-related"><code class="docutils literal notranslate"><span class="pre">select_related()</span></code></a></li>
<li><a class="reference internal" href="#prefetch-related"><code class="docutils literal notranslate"><span class="pre">prefetch_related()</span></code></a></li>
<li><a class="reference internal" href="#extra"><code class="docutils literal notranslate"><span class="pre">extra()</span></code></a></li>
<li><a class="reference internal" href="#defer"><code class="docutils literal notranslate"><span class="pre">defer()</span></code></a></li>
<li><a class="reference internal" href="#only"><code class="docutils literal notranslate"><span class="pre">only()</span></code></a></li>
<li><a class="reference internal" href="#using"><code class="docutils literal notranslate"><span class="pre">using()</span></code></a></li>
<li><a class="reference internal" href="#select-for-update"><code class="docutils literal notranslate"><span class="pre">select_for_update()</span></code></a></li>
<li><a class="reference internal" href="#raw"><code class="docutils literal notranslate"><span class="pre">raw()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#operators-that-return-new-querysets">返回新 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的操作符</a><ul>
<li><a class="reference internal" href="#and">AND（<code class="docutils literal notranslate"><span class="pre">&amp;</span></code>）</a></li>
<li><a class="reference internal" href="#or">OR（<code class="docutils literal notranslate"><span class="pre">|</span></code>）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#methods-that-do-not-return-querysets">不返回 <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> 的方法</a><ul>
<li><a class="reference internal" href="#get"><code class="docutils literal notranslate"><span class="pre">get()</span></code></a></li>
<li><a class="reference internal" href="#create"><code class="docutils literal notranslate"><span class="pre">create()</span></code></a></li>
<li><a class="reference internal" href="#get-or-create"><code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code></a></li>
<li><a class="reference internal" href="#update-or-create"><code class="docutils literal notranslate"><span class="pre">update_or_create()</span></code></a></li>
<li><a class="reference internal" href="#bulk-create"><code class="docutils literal notranslate"><span class="pre">bulk_create()</span></code></a></li>
<li><a class="reference internal" href="#bulk-update"><code class="docutils literal notranslate"><span class="pre">bulk_update()</span></code></a></li>
<li><a class="reference internal" href="#count"><code class="docutils literal notranslate"><span class="pre">count()</span></code></a></li>
<li><a class="reference internal" href="#in-bulk"><code class="docutils literal notranslate"><span class="pre">in_bulk()</span></code></a></li>
<li><a class="reference internal" href="#iterator"><code class="docutils literal notranslate"><span class="pre">iterator()</span></code></a><ul>
<li><a class="reference internal" href="#with-server-side-cursors">使用服务器端游标</a></li>
<li><a class="reference internal" href="#without-server-side-cursors">没有服务器端游标</a></li>
</ul>
</li>
<li><a class="reference internal" href="#latest"><code class="docutils literal notranslate"><span class="pre">latest()</span></code></a></li>
<li><a class="reference internal" href="#earliest"><code class="docutils literal notranslate"><span class="pre">earliest()</span></code></a></li>
<li><a class="reference internal" href="#first"><code class="docutils literal notranslate"><span class="pre">first()</span></code></a></li>
<li><a class="reference internal" href="#last"><code class="docutils literal notranslate"><span class="pre">last()</span></code></a></li>
<li><a class="reference internal" href="#aggregate"><code class="docutils literal notranslate"><span class="pre">aggregate()</span></code></a></li>
<li><a class="reference internal" href="#exists"><code class="docutils literal notranslate"><span class="pre">exists()</span></code></a></li>
<li><a class="reference internal" href="#update"><code class="docutils literal notranslate"><span class="pre">update()</span></code></a><ul>
<li><a class="reference internal" href="#ordered-queryset">Ordered queryset</a></li>
</ul>
</li>
<li><a class="reference internal" href="#delete"><code class="docutils literal notranslate"><span class="pre">delete()</span></code></a></li>
<li><a class="reference internal" href="#as-manager"><code class="docutils literal notranslate"><span class="pre">as_manager()</span></code></a></li>
<li><a class="reference internal" href="#explain"><code class="docutils literal notranslate"><span class="pre">explain()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#field-lookups"><code class="docutils literal notranslate"><span class="pre">Field</span></code> 查找</a><ul>
<li><a class="reference internal" href="#exact"><code class="docutils literal notranslate"><span class="pre">exact</span></code></a></li>
<li><a class="reference internal" href="#iexact"><code class="docutils literal notranslate"><span class="pre">iexact</span></code></a></li>
<li><a class="reference internal" href="#contains"><code class="docutils literal notranslate"><span class="pre">contains</span></code></a></li>
<li><a class="reference internal" href="#icontains"><code class="docutils literal notranslate"><span class="pre">icontains</span></code></a></li>
<li><a class="reference internal" href="#in"><code class="docutils literal notranslate"><span class="pre">in</span></code></a></li>
<li><a class="reference internal" href="#gt"><code class="docutils literal notranslate"><span class="pre">gt</span></code></a></li>
<li><a class="reference internal" href="#gte"><code class="docutils literal notranslate"><span class="pre">gte</span></code></a></li>
<li><a class="reference internal" href="#lt"><code class="docutils literal notranslate"><span class="pre">lt</span></code></a></li>
<li><a class="reference internal" href="#lte"><code class="docutils literal notranslate"><span class="pre">lte</span></code></a></li>
<li><a class="reference internal" href="#startswith"><code class="docutils literal notranslate"><span class="pre">startswith</span></code></a></li>
<li><a class="reference internal" href="#istartswith"><code class="docutils literal notranslate"><span class="pre">istartswith</span></code></a></li>
<li><a class="reference internal" href="#endswith"><code class="docutils literal notranslate"><span class="pre">endswith</span></code></a></li>
<li><a class="reference internal" href="#iendswith"><code class="docutils literal notranslate"><span class="pre">iendswith</span></code></a></li>
<li><a class="reference internal" href="#range"><code class="docutils literal notranslate"><span class="pre">range</span></code></a></li>
<li><a class="reference internal" href="#date"><code class="docutils literal notranslate"><span class="pre">date</span></code></a></li>
<li><a class="reference internal" href="#year"><code class="docutils literal notranslate"><span class="pre">year</span></code></a></li>
<li><a class="reference internal" href="#iso-year"><code class="docutils literal notranslate"><span class="pre">iso_year</span></code></a></li>
<li><a class="reference internal" href="#month"><code class="docutils literal notranslate"><span class="pre">month</span></code></a></li>
<li><a class="reference internal" href="#day"><code class="docutils literal notranslate"><span class="pre">day</span></code></a></li>
<li><a class="reference internal" href="#week"><code class="docutils literal notranslate"><span class="pre">week</span></code></a></li>
<li><a class="reference internal" href="#week-day"><code class="docutils literal notranslate"><span class="pre">week_day</span></code></a></li>
<li><a class="reference internal" href="#iso-week-day"><code class="docutils literal notranslate"><span class="pre">iso_week_day</span></code></a></li>
<li><a class="reference internal" href="#quarter"><code class="docutils literal notranslate"><span class="pre">quarter</span></code></a></li>
<li><a class="reference internal" href="#time"><code class="docutils literal notranslate"><span class="pre">time</span></code></a></li>
<li><a class="reference internal" href="#hour"><code class="docutils literal notranslate"><span class="pre">hour</span></code></a></li>
<li><a class="reference internal" href="#minute"><code class="docutils literal notranslate"><span class="pre">minute</span></code></a></li>
<li><a class="reference internal" href="#second"><code class="docutils literal notranslate"><span class="pre">second</span></code></a></li>
<li><a class="reference internal" href="#isnull"><code class="docutils literal notranslate"><span class="pre">isnull</span></code></a></li>
<li><a class="reference internal" href="#regex"><code class="docutils literal notranslate"><span class="pre">regex</span></code></a></li>
<li><a class="reference internal" href="#iregex"><code class="docutils literal notranslate"><span class="pre">iregex</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#aggregation-functions">聚合函数</a><ul>
<li><a class="reference internal" href="#expressions"><code class="docutils literal notranslate"><span class="pre">expressions</span></code></a></li>
<li><a class="reference internal" href="#output-field"><code class="docutils literal notranslate"><span class="pre">output_field</span></code></a></li>
<li><a class="reference internal" href="#aggregate-filter"><code class="docutils literal notranslate"><span class="pre">filter</span></code></a></li>
<li><a class="reference internal" href="#id7"><code class="docutils literal notranslate"><span class="pre">**extra</span></code></a></li>
<li><a class="reference internal" href="#avg"><code class="docutils literal notranslate"><span class="pre">Avg</span></code></a></li>
<li><a class="reference internal" href="#id8"><code class="docutils literal notranslate"><span class="pre">Count</span></code></a></li>
<li><a class="reference internal" href="#max"><code class="docutils literal notranslate"><span class="pre">Max</span></code></a></li>
<li><a class="reference internal" href="#min"><code class="docutils literal notranslate"><span class="pre">Min</span></code></a></li>
<li><a class="reference internal" href="#stddev"><code class="docutils literal notranslate"><span class="pre">StdDev</span></code></a></li>
<li><a class="reference internal" href="#sum"><code class="docutils literal notranslate"><span class="pre">Sum</span></code></a></li>
<li><a class="reference internal" href="#variance"><code class="docutils literal notranslate"><span class="pre">Variance</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#query-related-tools">查询相关工具</a><ul>
<li><a class="reference internal" href="#q-objects"><code class="docutils literal notranslate"><span class="pre">Q()</span></code> 对象</a></li>
<li><a class="reference internal" href="#prefetch-objects"><code class="docutils literal notranslate"><span class="pre">Prefetch()</span></code> 对象</a></li>
<li><a class="reference internal" href="#prefetch-related-objects"><code class="docutils literal notranslate"><span class="pre">prefetch_related_objects()</span></code></a></li>
<li><a class="reference internal" href="#filteredrelation-objects"><code class="docutils literal notranslate"><span class="pre">FilteredRelation()</span></code> 对象</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="instances.html"
                        title="上一章">模型实例参考</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="lookups.html"
                        title="下一章">查找 API 参考</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/ref/models/querysets.txt"
            rel="nofollow">显示源代码</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>快速搜索</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="转向" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">12月 07, 2021</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="instances.html" title="模型实例参考">previous</a>
     |
    <a href="../index.html" title="API 参考" accesskey="U">up</a>
   |
    <a href="lookups.html" title="查找 API 参考">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>